home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / otm3d095 / mode13h.asm < prev    next >
Encoding:
Assembly Source File  |  1994-12-12  |  90.2 KB  |  4,335 lines

  1. ;       mode13h v0.90ß released 11-01-94
  2. ;
  3. ;       32 bit mode 13h graphics routines
  4. ;       by Voltaire/OTM
  5. ;       Copyright (C) 1994 Zach Mortensen
  6. ;
  7. ;       email -
  8. ;       mortens1@nersc.gov
  9. ;
  10. ;       NOTE  - These routines are designed to operate in the FLAT MEMORY
  11. ;       MODEL ONLY!  Therefore, you HAVE to be using protected mode to use
  12. ;       them.  If you're writing 32 bit code and NOT using protected mode,
  13. ;       you should be slapped for your laziness and lack of foresight.
  14. ;       Go spend $200 and buy Watcom C++ v10.0, it ROCKS, and it comes with
  15. ;       DOS4GW, Rational Systems' 32 bit DOS extender.  Will these routines
  16. ;       work with Tran's PMODE?  I DON'T KNOW.  I picked up Tran's code long
  17. ;       ago and found it impossible to use from within C++.  I write all of
  18. ;       my code in C++ with the exception of speed critical things like
  19. ;       graphics primitives, and extremely low level code such as sound
  20. ;       routines, which I do in assembler; so I never really gave PMODE
  21. ;       much of a chance (sorry, Tran).
  22. ;
  23. ;       DISCLAIMER - I am not an assembler programmer.  I do not profess to
  24. ;       be an assembler programmer.  This code is all original.  This code
  25. ;       is all assembler.  Therefore, this code CONTAINS SOME BUGS.  I AM
  26. ;       AWARE OF THAT.  If you find any (and you will), please let me know.
  27. ;       As far as optimization goes, I'm sure I've done a few things wrong
  28. ;       here and there, but on the whole this is some pretty fast code.  If
  29. ;       you have any ideas on how to further optimize, please let me know
  30. ;       as well.
  31. ;
  32.  
  33.  
  34.         .386p
  35.  
  36.         .code
  37.  
  38. ; Data goes here (in the CODE segment?!?!  AAAAAAAAARRRGH!!)
  39.  
  40.  
  41.         vidSeg          dd      000A0000h
  42.         virtPage        dd      ?
  43.         curPage         dd      ?
  44.         zBuf            dd      ?
  45.  
  46.  
  47.         ; data for the triangle routines
  48.  
  49.         lEdge           dd      200 dup(0)
  50.         rEdge           dd      200 dup(0)
  51.         lColor          dd      200 dup(0)
  52.         rColor          dd      200 dup(0)
  53.         lZ              dd      200 dup(0)
  54.         rZ              dd      200 dup(0)
  55.  
  56.         xTop            dd      0
  57.         yTop            dd      0
  58.         zTop            dd      0
  59.         cTop            dd      0
  60.         xMid            dd      0
  61.         yMid            dd      0
  62.         zMid            dd      0
  63.         cMid            dd      0
  64.         xBot            dd      0
  65.         yBot            dd      0
  66.         zBot            dd      0
  67.         cBot            dd      0
  68.  
  69.         rCount          dd      0
  70.  
  71.         temp            dd      0
  72.  
  73.         zRatio          dd      0       ; dzdx = constant for each poly
  74.         cRatio          dd      0       ; dcdx = constant for each poly
  75.  
  76.         xBres           dd      0
  77.         yBres           dd      0
  78.         cBres           dd      0
  79.  
  80.         dxdy            dd      0
  81.  
  82.         ; stuff for the regHline routine
  83.  
  84.         color           dd      0
  85.         scanLine        dd      0
  86.         rhlColor        dd      0
  87.  
  88.         ; for tDrawBitmap routine
  89.  
  90.         sPos            dd      0
  91.         dPos            dd      0
  92.         xOffset         dd      0
  93.         yOffset         dd      0
  94.         oWidth          dd      0       ; original width
  95.         oHeight         dd      0       ; original height
  96.         nWidth          dd      0       ; new width
  97.         nHeight         dd      0       ; new height
  98.  
  99.         ; table of colors (dwords) so we don't have to calculate them
  100.         ; every time
  101.  
  102.         ; I never could get this to work the way I wanted it to...;)
  103.  
  104. dwColor label dword
  105.  
  106.         dd 000000000h
  107.     dd 001010101h, 002020202h, 003030303h, 004040404h
  108.     dd 005050505h, 006060606h, 007070707h, 008080808h
  109.     dd 009090909h, 00A0A0A0Ah, 00B0B0B0Bh, 00C0C0C0Ch
  110.     dd 00D0D0D0Dh, 00E0E0E0Eh, 00F0F0F0Fh, 010101010h
  111.     dd 011111111h, 012121212h, 013131313h, 014141414h
  112.     dd 015151515h, 016161616h, 017171717h, 018181818h
  113.     dd 019191919h, 01A1A1A1Ah, 01B1B1B1Bh, 01C1C1C1Ch
  114.     dd 01D1D1D1Dh, 01E1E1E1Eh, 01F1F1F1Fh, 020202020h
  115.     dd 021212121h, 022222222h, 023232323h, 024242424h
  116.     dd 025252525h, 026262626h, 027272727h, 028282828h
  117.     dd 029292929h, 02A2A2A2Ah, 02B2B2B2Bh, 02C2C2C2Ch
  118.     dd 02D2D2D2Dh, 02E2E2E2Eh, 02F2F2F2Fh, 030303030h
  119.     dd 031313131h, 032323232h, 033333333h, 034343434h
  120.     dd 035353535h, 036363636h, 037373737h, 038383838h
  121.     dd 039393939h, 03A3A3A3Ah, 03B3B3B3Bh, 03C3C3C3Ch
  122.     dd 03D3D3D3Dh, 03E3E3E3Eh, 03F3F3F3Fh, 040404040h
  123.     dd 041414141h, 042424242h, 043434343h, 044444444h
  124.     dd 045454545h, 046464646h, 047474747h, 048484848h
  125.     dd 049494949h, 04A4A4A4Ah, 04B4B4B4Bh, 04C4C4C4Ch
  126.     dd 04D4D4D4Dh, 04E4E4E4Eh, 04F4F4F4Fh, 050505050h
  127.     dd 051515151h, 052525252h, 053535353h, 054545454h
  128.     dd 055555555h, 056565656h, 057575757h, 058585858h
  129.     dd 059595959h, 05A5A5A5Ah, 05B5B5B5Bh, 05C5C5C5Ch
  130.     dd 05D5D5D5Dh, 05E5E5E5Eh, 05F5F5F5Fh, 060606060h
  131.     dd 061616161h, 062626262h, 063636363h, 064646464h
  132.     dd 065656565h, 066666666h, 067676767h, 068686868h
  133.     dd 069696969h, 06A6A6A6Ah, 06B6B6B6Bh, 06C6C6C6Ch
  134.     dd 06D6D6D6Dh, 06E6E6E6Eh, 06F6F6F6Fh, 070707070h
  135.     dd 071717171h, 072727272h, 073737373h, 074747474h
  136.     dd 075757575h, 076767676h, 077777777h, 078787878h
  137.     dd 079797979h, 07A7A7A7Ah, 07B7B7B7Bh, 07C7C7C7Ch
  138.     dd 07D7D7D7Dh, 07E7E7E7Eh, 07F7F7F7Fh, 080808080h
  139.     dd 081818181h, 082828282h, 083838383h, 084848484h
  140.     dd 085858585h, 086868686h, 087878787h, 088888888h
  141.     dd 089898989h, 08A8A8A8Ah, 08B8B8B8Bh, 08C8C8C8Ch
  142.     dd 08D8D8D8Dh, 08E8E8E8Eh, 08F8F8F8Fh, 090909090h
  143.     dd 091919191h, 092929292h, 093939393h, 094949494h
  144.     dd 095959595h, 096969696h, 097979797h, 098989898h
  145.     dd 099999999h, 09A9A9A9Ah, 09B9B9B9Bh, 09C9C9C9Ch
  146.     dd 09D9D9D9Dh, 09E9E9E9Eh, 09F9F9F9Fh, 0A0A0A0A0h
  147.     dd 0A1A1A1A1h, 0A2A2A2A2h, 0A3A3A3A3h, 0A4A4A4A4h
  148.     dd 0A5A5A5A5h, 0A6A6A6A6h, 0A7A7A7A7h, 0A8A8A8A8h
  149.     dd 0A9A9A9A9h, 0AAAAAAAAh, 0ABABABABh, 0ACACACACh
  150.     dd 0ADADADADh, 0AEAEAEAEh, 0AFAFAFAFh, 0B0B0B0B0h
  151.     dd 0B1B1B1B1h, 0B2B2B2B2h, 0B3B3B3B3h, 0B4B4B4B4h
  152.     dd 0B5B5B5B5h, 0B6B6B6B6h, 0B7B7B7B7h, 0B8B8B8B8h
  153.     dd 0B9B9B9B9h, 0BABABABAh, 0BBBBBBBBh, 0BCBCBCBCh
  154.     dd 0BDBDBDBDh, 0BEBEBEBEh, 0BFBFBFBFh, 0C0C0C0C0h
  155.     dd 0C1C1C1C1h, 0C2C2C2C2h, 0C3C3C3C3h, 0C4C4C4C4h
  156.     dd 0C5C5C5C5h, 0C6C6C6C6h, 0C7C7C7C7h, 0C8C8C8C8h
  157.     dd 0C9C9C9C9h, 0CACACACAh, 0CBCBCBCBh, 0CCCCCCCCh
  158.     dd 0CDCDCDCDh, 0CECECECEh, 0CFCFCFCFh, 0D0D0D0D0h
  159.     dd 0D1D1D1D1h, 0D2D2D2D2h, 0D3D3D3D3h, 0D4D4D4D4h
  160.     dd 0D5D5D5D5h, 0D6D6D6D6h, 0D7D7D7D7h, 0D8D8D8D8h
  161.     dd 0D9D9D9D9h, 0DADADADAh, 0DBDBDBDBh, 0DCDCDCDCh
  162.     dd 0DDDDDDDDh, 0DEDEDEDEh, 0DFDFDFDFh, 0E0E0E0E0h
  163.     dd 0E1E1E1E1h, 0E2E2E2E2h, 0E3E3E3E3h, 0E4E4E4E4h
  164.     dd 0E5E5E5E5h, 0E6E6E6E6h, 0E7E7E7E7h, 0E8E8E8E8h
  165.     dd 0E9E9E9E9h, 0EAEAEAEAh, 0EBEBEBEBh, 0ECECECECh
  166.     dd 0EDEDEDEDh, 0EEEEEEEEh, 0EFEFEFEFh, 0F0F0F0F0h
  167.     dd 0F1F1F1F1h, 0F2F2F2F2h, 0F3F3F3F3h, 0F4F4F4F4h
  168.     dd 0F5F5F5F5h, 0F6F6F6F6h, 0F7F7F7F7h, 0F8F8F8F8h
  169.     dd 0F9F9F9F9h, 0FAFAFAFAh, 0FBFBFBFBh, 0FCFCFCFCh
  170.         dd 0FDFDFDFDh, 0FEFEFEFEh, 0FFFFFFFFh
  171.  
  172.  
  173.  
  174.  
  175. ; Code starts here
  176.  
  177. ;----------------------------------------------
  178. ; void setMode13h(char *vPage)
  179. ;----------------------------------------------
  180. ;
  181. ; Sets the video mode to 320x200x256 (REAL hard), and sets up page flipping,
  182. ; if you want to use it.  Sometimes (e.g. texture mappint) it's faster to
  183. ; write to the VGA one pixel at a time than it is to flip pages...don't ask
  184. ; me why.
  185. ;
  186. ; vPage = pointer to a buffer YOU have already allocated, better make it
  187. ; 64000 bytes (320x200) ... or MORE if you are in a generous mood.  I do this
  188. ; so you can access the virtual page from higher level code if you wish.
  189. ; The virtual page facilitates off screen drawing (should you set the active
  190. ; page to pVirtual (or 1)), which eliminates screen flicker and in most cases
  191. ; makes your animation appear to be smoother.  The virtual page tends to slow
  192. ; down gouraud shading and other drawing operations that write to the VGA
  193. ; one pixel at a time and do some calculating in between pixels.
  194.  
  195. sm13Stack struc
  196.                  dd  ?,? ; ebp, edi
  197.                  dd  ?   ; caller
  198.            zB    dd  ?   ; pointer to z-buffer (128k)
  199.            vPage dd  ?   ; pointer to virtual page
  200. sm13Stack ends
  201.  
  202.         public setMode13h
  203.  
  204. setMode13h proc
  205.  
  206.         push ebp
  207.         push edi
  208.         mov ebp, esp
  209.  
  210.         mov eax, 13h
  211.         int 10h
  212.  
  213.         mov eax, [ebp].vPage
  214.         mov virtPage, eax
  215.         mov eax, vidSeg
  216.         mov curPage, eax
  217.  
  218.         mov eax, [ebp].zB
  219.         mov zBuf, eax
  220.  
  221.         mov eax, 0
  222.         mov edi, virtPage
  223.         mov ecx, 16000
  224.         rep stosd
  225.  
  226.         mov edi, vidSeg
  227.         mov ecx, 16000
  228.         rep stosd
  229.  
  230.         mov edi, zBuf
  231.         mov eax, 07FFF7FFFh
  232.         mov ecx, 32000
  233.         rep stosd
  234.  
  235.         pop edi
  236.         pop ebp
  237.  
  238.         ret 4
  239.  
  240. setMode13h endp
  241.  
  242. ;--------------------
  243. ; void textMode(void)
  244. ;--------------------
  245. ;
  246. ; gets you back to 80x25...
  247. ;
  248.  
  249.         public textMode
  250.  
  251. textMode proc
  252.  
  253.         mov eax, 3
  254.         int 10h
  255.  
  256.         ret
  257.  
  258. textMode endp
  259.  
  260. ;--------------------------------------
  261. ;void setActivePage(int page)
  262. ;--------------------------------------
  263. ;
  264. ; Sets the page to be used for drawing, either the phyisical page (const
  265. ; pPhysical) or virtual page (const pVirtual).  REMEMBER that if you draw
  266. ; to the virtual page, you need to display it (flipVPage()) before you can
  267. ; see it.  Calling flipVPage() will copy the contents of the virtual page
  268. ; to the screen, regardless of which page is active, and does NOTHING else.
  269. ;
  270.  
  271.  
  272. sapStack struc
  273.                 dd  ?,? ; room for registers
  274.                 dd  ?   ; caller
  275.         aPage    dd  ?   ; new active page
  276. sapStack ends
  277.  
  278.         public setActivePage
  279.  
  280. setActivePage proc
  281.  
  282.         push ebp
  283.         push edi
  284.  
  285.         mov ebp, esp
  286.  
  287.         mov eax, [ebp].aPage
  288.         cmp eax, 0
  289.         jne sapVPage
  290.  
  291.         mov eax, vidSeg
  292.         mov curPage, eax
  293.         jmp sapDone
  294.  
  295. sapVPage:
  296.  
  297.         mov eax, virtPage
  298.         mov curPage, eax
  299.  
  300. sapDone:
  301.  
  302.         pop edi
  303.         pop ebp
  304.  
  305.         ret 4
  306.  
  307. setActivePage endp
  308.  
  309.  
  310. ;---------------------
  311. ; void flipVPage(void)
  312. ;---------------------
  313. ;
  314. ; flips the virtual page to the screen, displays what you have been drawing
  315. ; off screen.
  316.  
  317.  
  318.         public flipVPage
  319.  
  320. flipVPage proc
  321.  
  322.         push edi
  323.         push esi
  324.  
  325.         call syncDisplay
  326.  
  327.         mov esi, virtPage
  328.         mov edi, vidSeg
  329.         mov ecx, 16000
  330.  
  331.         cld
  332.         rep movsd
  333.  
  334.         pop esi
  335.         pop edi
  336.  
  337.         ret
  338.  
  339. flipVPage endp
  340.  
  341.  
  342. ; hline procedure used in poly filling, if you want to slow things down by
  343. ; calling it.  The poly3 function makes use of an inline version of this
  344. ; procedure which eliminates the stack pushes and calls.
  345.  
  346.  
  347. hlStack struc
  348.                 dd  ?,?         ; room for regs
  349.                 dd  ?           ; caller
  350.         hlcolor db  ?,?,?,?     ; color
  351.         hly     dd  ?           ; y
  352.         hlx2    dd  ?           ; x2
  353.         hlx1    dd  ?           ; x1
  354. hlStack ends
  355.  
  356.         public hline
  357.  
  358. hline proc
  359.  
  360.         push ebp
  361.         push edi
  362.         mov ebp, esp
  363.  
  364.         mov eax, [ebp].hly
  365.         mov ebx, 320
  366.         mul ebx
  367.  
  368.         mov edi, curPage
  369.  
  370.         mov ecx, [ebp].hlx1
  371.         mov ebx, [ebp].hlx2
  372.  
  373.         cmp ebx, ecx
  374.         jg hlDraw
  375.         xchg ebx, ecx
  376.  
  377. hlDraw: add eax, ecx
  378.         add edi, eax
  379.  
  380.         sub ebx, ecx
  381.         mov ecx, ebx
  382.         and ebx, 3
  383.         shr ecx, 2
  384.  
  385.         mov ah, [ebp].hlcolor
  386.         mov al, ah
  387.         movzx edx, ax
  388.         shl eax, 16
  389.         or eax, edx
  390.  
  391.         cld
  392.         rep stosd
  393.         mov ecx, ebx
  394.         rep stosb
  395.  
  396.         pop edi
  397.         pop ebp
  398.  
  399.         ret 16
  400.  
  401. hline endp
  402.  
  403. ;----------------------------------------
  404. ; void setPixel(int x, int y, int color)
  405. ;----------------------------------------
  406. ;
  407. ; Sets the pixel at (x, y) to color (color).  Does bounds checking to avoid
  408. ; the dreaded GP FAULT!
  409. ;
  410.  
  411.  
  412. spStack struc
  413.                   dd  ?,?         ; ebp, edi
  414.                   dd  ?           ; caller
  415.         setpColor dd  ?           ; color of pixel
  416.         setpY     dd  ?           ; Y value
  417.         setpX     dd  ?           ; X value
  418. spStack ends
  419.  
  420.         public setPixel
  421.  
  422. setPixel proc
  423.  
  424.         push ebp
  425.         push edi
  426.         mov ebp, esp
  427.  
  428.         mov eax, [ebp].setpY
  429.         mov ecx, [ebp].setpX
  430.  
  431.         cmp eax, 0
  432.         jl setPixDone
  433.         cmp eax, 199
  434.         jg setPixDone
  435.         cmp ecx, 0
  436.         jl setPixDone
  437.         cmp ecx, 319
  438.         jg setPixDone
  439.  
  440.         mov ebx, 320
  441.         mul ebx
  442.         add eax, ecx
  443.  
  444.         mov edi, eax
  445.         add edi, curPage
  446.  
  447.         mov eax, [ebp].setpColor
  448.         stosb
  449.  
  450. setPixDone:
  451.         pop edi
  452.         pop ebp
  453.  
  454.         ret 12
  455.  
  456. setPixel endp
  457.  
  458. ;-----------------------
  459. ; void syncDisplay(void)
  460. ;-----------------------
  461. ;
  462. ; waits for the current vertical retrace to end, then waits for the start
  463. ; of the next one.
  464. ;
  465.  
  466.         public syncDisplay
  467.  
  468. syncDisplay proc
  469.  
  470.         mov     dx, 03DAh
  471.  
  472. wait0:
  473.         in      al, dx
  474.         test    al, 08h
  475.         jnz     wait0
  476.  
  477. wait1:
  478.         in      al, dx
  479.         test    al, 08h
  480.         jz      wait1
  481.  
  482.         ret
  483.  
  484. syncDisplay endp
  485.  
  486.  
  487. ; a few basic mouse routines...I never implemented anything more in this
  488. ; library.  Mice are easy, just refer to any interrupt listing for help.
  489.  
  490.         public initMouse
  491.  
  492. initMouse proc
  493.  
  494.         mov ax, 0
  495.         int 33h
  496.  
  497.         ret
  498.  
  499. initMouse endp
  500.  
  501.         public showMouse
  502.  
  503. showMouse proc
  504.  
  505.         mov ax, 1
  506.         int 33h
  507.  
  508.         ret
  509.  
  510. showMouse endp
  511.  
  512.         public hideMouse
  513.  
  514. hideMouse proc
  515.  
  516.         mov ax, 2
  517.         int 33h
  518.  
  519.         ret
  520.  
  521. hideMouse endp
  522.  
  523.  
  524. ;----------------------------------------------------------------------------
  525. ; void poly3(int x1, int y1, int x2, int y2, int x3, int y3, int c);
  526. ;----------------------------------------------------------------------------
  527. ;
  528. ; Draws a clipped triangular polygon bounded by (x1,y1) (x2,y2) (x3,y3)
  529. ; in color c.  This routine does NOT do shading!
  530. ;
  531.  
  532.  
  533. p3Stack struc
  534.                 dd  ?,?,?       ; room for regs
  535.                 dd  ?           ; caller
  536.         p3color db  ?,?,?,?     ; color to fill
  537.         p3y3    dd  ?           ; y3
  538.         p3x3    dd  ?           ; x3
  539.         p3y2    dd  ?           ; y2
  540.         p3x2    dd  ?           ; x2
  541.         p3y1    dd  ?           ; y1
  542.         p3x1    dd  ?           ; x1
  543.  
  544. p3Stack ends
  545.  
  546.         public poly3
  547.  
  548. poly3 proc
  549.  
  550.         push ebp
  551.         push edi
  552.         push esi
  553.  
  554.         mov ebp, esp
  555.  
  556.         mov eax, [ebp].p3y1
  557.         mov ebx, [ebp].p3y2
  558.         mov ecx, [ebp].p3y3
  559.  
  560.         ; sort the points based on y values
  561.  
  562. yComp1: cmp eax, ebx
  563.         jg y2top
  564.  
  565.         mov yTop, eax
  566.         mov edx, [ebp].p3x1
  567.         mov xTop, edx
  568.  
  569.         mov yBot, ebx
  570.         mov edx, [ebp].p3x2
  571.         mov xBot, edx
  572.  
  573.         jmp yComp2
  574.  
  575. y2top:  mov yTop, ebx
  576.         mov edx, [ebp].p3x2
  577.         mov xTop, edx
  578.  
  579.         mov yBot, eax
  580.         mov edx, [ebp].p3x1
  581.         mov xBot, edx
  582.  
  583. yComp2: cmp ecx, yTop
  584.         jg yTopOK
  585.  
  586.         mov yTop, ecx
  587.         mov edx, [ebp].p3x3
  588.         mov xTop, edx
  589.  
  590.         cmp eax, ebx
  591.         jg y2mid
  592.  
  593.         mov yMid, eax
  594.         mov edx, [ebp].p3x1
  595.         mov xMid, edx
  596.  
  597.         mov yBot, ebx
  598.         mov edx, [ebp].p3x2
  599.         mov xBot, edx
  600.  
  601.         jmp yCompDone
  602.  
  603. y2mid:  mov yMid, ebx
  604.         mov edx, [ebp].p3x2
  605.         mov xMid, edx
  606.  
  607.         mov yBot, eax
  608.         mov edx, [ebp].p3x1
  609.         mov xBot, edx
  610.  
  611.         jmp yCompDone
  612.  
  613. yTopOK: cmp ecx, yBot
  614.         jg ybBad
  615.  
  616.         mov yMid, ecx
  617.         mov edx, [ebp].p3x3
  618.         mov xMid, edx
  619.  
  620.         jmp yCompDone
  621.  
  622. ybBad:  mov eax, yBot
  623.         mov ebx, xBot
  624.  
  625.         mov yMid, eax
  626.         mov xMid, ebx
  627.  
  628.         mov yBot, ecx
  629.         mov edx, [ebp].p3x3
  630.         mov xBot, edx
  631.  
  632. yCompDone:
  633.  
  634.         mov eax, yTop
  635.         mov ebx, yBot
  636.         cmp eax, 199
  637.         jg fillDone
  638.         cmp ebx, 0
  639.         jl fillDone
  640.  
  641.         ; now calculate the x values at each scanline for the longest side.
  642.  
  643.         mov eax, xBot
  644.         mov ebx, xTop
  645.         sub eax, ebx
  646.         shl eax, 16
  647.  
  648.         mov ecx, yBot
  649.         mov edx, yTop
  650.         sub ecx, edx
  651.  
  652.         jecxz edge1Horz         ; skip the div if denominator = 0
  653.         cmp eax, 0
  654.         jge edge1Pos
  655.  
  656.         neg eax
  657.         xor edx, edx
  658.         div ecx
  659.         neg eax
  660.  
  661.         jmp edge1Continue
  662.  
  663. edge1Horz:
  664.         ;xor eax, eax
  665.         ;xor edx, edx
  666.         ;jmp edge1Continue
  667.  
  668.         jmp edge2Start
  669.  
  670. edge1Pos:
  671.         xor edx, edx
  672.         div ecx
  673.  
  674. edge1Continue:
  675.         mov ecx, yBot
  676.         mov ebx, yTop
  677.         sub ecx, ebx
  678.  
  679.         shl ebx, 2
  680.         lea edi, lEdge
  681.         add edi, ebx
  682.  
  683.         xor ebx, ebx
  684.         mov edx, xTop
  685.         mov esi, yTop
  686.  
  687.         align 4
  688.  
  689. edge1Loop:
  690.  
  691.         cmp esi, 0
  692.         jl skipThisLine1
  693.         cmp esi, 199
  694.         jg edge2Start
  695.  
  696.         ror ebx, 16
  697.         add dx, bx
  698.         movsx edx, dx
  699.         rol ebx, 16
  700.         movzx ebx, bx
  701.         mov [edi], edx
  702.  
  703. skipThisLine1:
  704.         add ebx, eax
  705.         add edi, 4
  706.         inc esi
  707.         dec ecx
  708.         jns edge1Loop
  709.  
  710.         ; calculate x values for next side
  711.  
  712. edge2Start:
  713.         mov eax, xBot
  714.         mov ebx, xMid
  715.         sub eax, ebx
  716.         shl eax, 16
  717.  
  718.         mov ecx, yBot
  719.         mov edx, yMid
  720.         sub ecx, edx
  721.  
  722.         jecxz edge2Horz
  723.         cmp eax, 0
  724.         jge edge2Pos
  725.  
  726.         neg eax
  727.         xor edx, edx
  728.         div ecx
  729.         neg eax
  730.         jmp edge2Continue
  731.  
  732. edge2Horz:
  733.         ;xor eax, eax
  734.         ;xor edx, edx
  735.         ;jmp edge2Continue
  736.         jmp edge3Start
  737.  
  738. edge2Pos:
  739.         xor edx, edx
  740.         div ecx
  741.  
  742. edge2Continue:
  743.         mov ecx, yBot
  744.         mov ebx, yMid
  745.         sub ecx, ebx
  746.  
  747.         shl ebx, 2
  748.         lea edi, rEdge
  749.         add edi, ebx
  750.  
  751.         xor ebx, ebx
  752.         mov edx, xMid
  753.         mov esi, yMid
  754.  
  755.         align 4
  756.  
  757. edge2Loop:
  758.  
  759.         cmp esi, 0
  760.         jl skipThisLine2
  761.         cmp esi, 199
  762.         jg edge3Start
  763.  
  764.         ror ebx, 16
  765.         add dx, bx
  766.         movsx edx, dx
  767.         rol ebx, 16
  768.         movzx ebx, bx
  769.         mov [edi], edx
  770.  
  771. skipThisLine2:
  772.         add ebx, eax
  773.         add edi, 4
  774.         inc esi
  775.         dec ecx
  776.         jns edge2Loop
  777.  
  778.         ; calculate x values for last side
  779.  
  780. edge3Start:
  781.         mov eax, xMid
  782.         mov ebx, xTop
  783.         sub eax, ebx
  784.         shl eax, 16
  785.  
  786.         mov ecx, yMid
  787.         mov edx, yTop
  788.         sub ecx, edx
  789.  
  790.         jecxz edge3Horz
  791.         cmp eax, 0
  792.         jge edge3Pos
  793.  
  794.         neg eax
  795.         xor edx, edx
  796.         div ecx
  797.         neg eax
  798.  
  799.         jmp edge3Continue
  800.  
  801. edge3Horz:
  802.         ;xor eax, eax            ; zero ratio
  803.         ;xor edx, edx
  804.         ;jmp edge3Continue
  805.         jmp fillStart
  806.  
  807. edge3Pos:
  808.         xor edx, edx
  809.         div ecx
  810.  
  811. edge3Continue:
  812.         mov ecx, yMid
  813.         mov ebx, yTop
  814.         sub ecx, ebx
  815.  
  816.         shl ebx, 2
  817.         lea edi, rEdge
  818.         add edi, ebx
  819.  
  820.         xor ebx, ebx
  821.         mov edx, xTop
  822.         mov esi, yTop
  823.  
  824.         align 4
  825.  
  826. edge3Loop:
  827.  
  828.         cmp esi, 0
  829.         jl skipThisLine3
  830.         cmp esi, 199
  831.         jg fillStart
  832.  
  833.         ror ebx, 16
  834.         add dx, bx
  835.         movsx edx, dx
  836.         rol ebx, 16
  837.         movzx ebx, bx
  838.         mov [edi], edx
  839.  
  840. skipThisLine3:
  841.         add ebx, eax
  842.         add edi, 4
  843.         inc esi
  844.         dec ecx
  845.         jns edge3Loop
  846.  
  847.         ; time to fill...
  848.  
  849. fillStart:
  850.  
  851.         mov eax, yTop
  852.         mov ebx, yBot
  853.  
  854.         cmp eax, 0
  855.         jge checkBot
  856.         xor eax, eax
  857.         mov yTop, eax
  858.  
  859. checkBot:
  860.         cmp ebx, 199
  861.         jle fillNOW
  862.         mov ebx, 199
  863.         mov yBot, ebx
  864.  
  865. fillNOW:
  866.         lea esi, lEdge
  867.         lea edi, rEdge
  868.  
  869.         mov dl, [ebp].p3color
  870.         mov dh, dl
  871.         movzx edx, dx
  872.         mov eax, edx
  873.         shl eax, 16
  874.         or edx, eax
  875.         mov rhlColor, edx
  876.  
  877.         mov ecx, yTop
  878.         mov ebx, yBot
  879.         shl ecx, 2
  880.         add esi, ecx
  881.         add edi, ecx
  882.         shr ecx, 2
  883.  
  884.         align 4
  885.  
  886. fillME: push ecx
  887.  
  888.         ; another way to draw the hline, with register calls rather than
  889.         ; stack pushes to improve speed
  890.         ;
  891.         ; ON ENTRY
  892.         ; [esi] = x1
  893.         ; [edi] = x2
  894.         ; ecx = y
  895.         ; rhlColor = color to fill line with as a dword, that is, to draw
  896.         ;            a line of color 1, rhlColor would be 01010101
  897.  
  898.         ;public regHline
  899.  
  900.         mov eax, 320
  901.         xor edx, edx
  902.         mul ecx
  903.  
  904.         mov ecx, [esi]
  905.         mov ebx, [edi]
  906.  
  907.         cmp ebx, ecx
  908.         jg rhlDraw
  909.         xchg ebx, ecx
  910.  
  911. rhlDraw:
  912.  
  913.         cmp ecx, 319
  914.         jg nextLine
  915.  
  916.         cmp ebx, 0
  917.         jl nextLine
  918.  
  919. checkX2:
  920.         cmp ebx, 319
  921.         jle checkX1
  922.         mov ebx, 319
  923.  
  924. checkX1:
  925.         cmp ecx, 0
  926.         jge x1OKToo
  927.         xor ecx, ecx
  928.  
  929. x1OKToo:
  930.         push edi
  931.         add eax, ecx
  932.         mov edi, curPage
  933.         add edi, eax
  934.  
  935.         sub ebx, ecx
  936.         mov ecx, ebx
  937.         and ebx, 3
  938.         shr ecx, 2
  939.  
  940.         mov eax, rhlColor
  941.  
  942.         cld
  943.         rep stosd
  944.         mov ecx, ebx
  945.         rep stosb
  946.  
  947.         pop edi
  948.  
  949.         ; end of the rhline proc (used to be a proc anyway...)
  950.  
  951. nextLine:
  952.         pop ecx
  953.  
  954.         add esi, 4
  955.         add edi, 4
  956.         inc ecx
  957.         cmp ecx, yBot
  958.         jg fillDone
  959.         jmp fillME
  960.  
  961. fillDone:
  962.  
  963.         pop esi
  964.         pop edi
  965.         pop ebp
  966.  
  967.         ret 28
  968.  
  969. poly3 endp
  970.  
  971. ;----------------------------
  972. ; void clearScreen(int color)
  973. ;----------------------------
  974. ;
  975. ; fills the screen with color (color).  This is perhaps the most difficult
  976. ; thing I've ever written...heheh
  977. ;
  978.  
  979. csStack struc
  980.  
  981.                 dd  ?,?         ; ebp, edi
  982.                 dd  ?           ; caller
  983.         csColor db  ?,?,?,?     ; color
  984.  
  985. csStack ends
  986.  
  987.         public clearScreen
  988.  
  989. clearScreen proc
  990.  
  991.         push ebp
  992.         push edi
  993.  
  994.         mov ebp, esp
  995.  
  996.         mov edi, curPage
  997.         mov ecx, 16000
  998.         mov al, [ebp].csColor
  999.         mov ah, al
  1000.         movzx edx, ax
  1001.         shl eax, 16
  1002.         or eax, edx
  1003.  
  1004.         rep stosd
  1005.  
  1006.         pop edi
  1007.         pop ebp
  1008.  
  1009.         ret 4
  1010.  
  1011. clearScreen endp
  1012.  
  1013.  
  1014. ; Palette routines courtesy of Matt Pritchard (MODEX).  Something went wrong
  1015. ; with the load_dac_registers routine in the conversion to 32 bit and pmode,
  1016. ; and I haven't found the time to correct it yet...what a lazy bum I am!
  1017. ; I've been using repeated calls to the set_dac_register routine instead...
  1018.  
  1019. ;=================================================
  1020. ;SET_DAC_REGISTER (Register%, Red%, Green%, Blue%)
  1021. ;=================================================
  1022. ;
  1023. ; Sets a single (RGB) Vga Palette Register
  1024. ;
  1025. ; ENTRY: Register = The DAC # to modify (0-255)
  1026. ;        Red      = The new Red Intensity (0-63)
  1027. ;        Green    = The new Green Intensity (0-63)
  1028. ;        Blue     = The new Blue Intensity (0-63)
  1029. ;
  1030. ; EXIT:  No meaningful values returned
  1031. ;
  1032.  
  1033. SDR_STACK   STRUC
  1034.                     DD  ?   ; eBP
  1035.                     DD  ?   ; Caller
  1036.     SDR_Blue        DB  ?,?,?,? ; Blue Data Value
  1037.     SDR_Green       DB  ?,?,?,? ; Green Data Value
  1038.     SDR_Red         DB  ?,?,?,? ; Red Data Value
  1039.     SDR_Register    DB  ?,?,?,? ; Palette Register #
  1040. SDR_STACK   ENDS
  1041.  
  1042.     PUBLIC  SET_DAC_REGISTER
  1043.  
  1044. SET_DAC_REGISTER    PROC
  1045.  
  1046.     PUSH    eBP                  ; Save BP
  1047.     MOV     eBP, eSP              ; Set up Stack Frame
  1048.  
  1049.     ; Select which DAC Register to modify
  1050.  
  1051.     mov     dx, 03C8h
  1052.     mov     al, [eBP].SDR_Register
  1053.     out     dx, al
  1054.  
  1055.     MOV     DX, 03C9h           ; Dac Data Register
  1056.     mov     al, [eBP].SDR_Red    ; Set Red Intensity
  1057.     out     dx, al
  1058.     mov     al, [eBP].SDR_Green  ; Set Green Intensity
  1059.     out     dx, al
  1060.     mov     al, [eBP].SDR_Blue   ; Set Blue Intensity
  1061.     out     dx, al
  1062.  
  1063.     POP     eBP                  ; Restore Registers
  1064.     RET     16                  ; Exit & Clean Up Stack
  1065.  
  1066. SET_DAC_REGISTER    ENDP
  1067.  
  1068.  
  1069. ;===========================================================
  1070. ;LOAD_DAC_REGISTERS (SEG PalData, StartReg%, EndReg%, Sync%)
  1071. ;===========================================================
  1072. ;
  1073. ; Sets a Block of Vga Palette Registers
  1074. ;
  1075. ; ENTRY: PalData  = Far Pointer to Block of palette data
  1076. ;        StartReg = First Register # in range to set (0-255)
  1077. ;        EndReg   = Last Register # in Range to set (0-255)
  1078. ;        Sync     = Wait for Vertical Retrace Flag (Boolean)
  1079. ;
  1080. ; EXIT:  No meaningful values returned
  1081. ;
  1082. ; NOTES: PalData is a linear array of 3 byte Palette values
  1083. ;        in the order: Red  (0-63), Green (0-63), Blue (0-63)
  1084. ;
  1085.  
  1086. LDR_STACK   STRUC
  1087.                     DD  ?,?     ; EBP, ESI
  1088.                     DD  ?       ; Caller
  1089.     LDR_Sync        DW  ?,?     ; Vertical Sync Flag
  1090.     LDR_EndReg      DB  ?,?,?,? ; Last Register #
  1091.     LDR_StartReg    DB  ?,?,?,? ; First Register #
  1092.     LDR_PalData     DD  ?       ; Far Ptr to Palette Data
  1093. LDR_STACK   ENDS
  1094.  
  1095.     PUBLIC  LOAD_DAC_REGISTERS
  1096.  
  1097. LOAD_DAC_REGISTERS  PROC
  1098.  
  1099.     PUSH    ebp
  1100.     push    esi                  ; Save Registers
  1101.     mov     ebp, esp              ; Set up Stack Frame
  1102.  
  1103.     mov     AX, [BP].LDR_Sync   ; Get Vertical Sync Flag
  1104.     or      AX, AX              ; is Sync Flag = 0?
  1105.     jz      @LDR_Load           ; if so, skip call
  1106.  
  1107.     call    syncDisplay         ; wait for vsync
  1108.  
  1109.     ; Determine register #'s, size to copy, etc
  1110.  
  1111. @LDR_Load:
  1112.  
  1113.     mov     esi, [BP].LDR_PalData    ; DS:SI -> Palette Data
  1114.     mov     DX, 03C8h      ; DAC register # selector
  1115.  
  1116.     xor     AX, ax
  1117.     xor     BX, bx                  ; Clear for byte loads
  1118.     mov     AL, [BP].LDR_StartReg   ; Get Start Register
  1119.     mov     BL, [BP].LDR_EndReg     ; Get End Register
  1120.  
  1121.     sub     BX, AX              ; BX = # of DAC registers -1
  1122.     inc     BX                  ; BX = # of DAC registers
  1123.     mov     CX, BX              ; CX = # of DAC registers
  1124.     add     CX, BX              ; CX =  "   " * 2
  1125.     add     CX, BX              ; CX =  "   " * 3
  1126.     cld                         ; Block OUTs forward
  1127.     out     DX, AL              ; set up correct register #
  1128.  
  1129.     ; Load a block of DAC Registers
  1130.  
  1131.     mov     DX, 03C9h    ; Dac Data Register
  1132.  
  1133.     rep     outsb               ; block set DAC registers
  1134.  
  1135.     POP     esi
  1136.     pop     ebp                  ; Restore Registers
  1137.  
  1138.     ret     20                  ; Exit & Clean Up Stack
  1139.  
  1140. LOAD_DAC_REGISTERS  ENDP
  1141.  
  1142. ;----------------------------------------------------
  1143. ; void ghline(int x1, int c1, int x2, int c2, int y);
  1144. ;----------------------------------------------------
  1145. ;
  1146. ; draws a horizontal line from (x1, y) to (x2, y) and interpolates colors
  1147. ; (byte granularity) from c1 to c2 in the process.  This is used to fill
  1148. ; polygons in the gpoly3 routine.  I really should make this an inline
  1149. ; procedure like I did with hline, but the call is so much more complex...
  1150. ; I figured it would take just about as long either way.  Clipping too...
  1151. ;
  1152.  
  1153.  
  1154. ghlStack struc
  1155.  
  1156.                 dd ?,?,?        ; ebp esi edi
  1157.                 dd ?            ; caller
  1158.         ghly    dd ?            ; y
  1159.         ghlc2   dd ?            ; c2
  1160.         ghlx2   dd ?            ; x2
  1161.         ghlc1   dd ?            ; c1
  1162.         ghlx1   dd ?            ; x1
  1163.  
  1164. ghlStack ends
  1165.  
  1166.         public gHline
  1167.  
  1168. gHline proc     ; gouraud hline routine
  1169.  
  1170.         push ebp
  1171.         push esi
  1172.         push edi
  1173.         mov ebp, esp
  1174.  
  1175.         mov eax, [ebp].ghly
  1176.         mov ebx, 320
  1177.         mul ebx
  1178.  
  1179.         mov edi, curPage
  1180.  
  1181.         mov ecx, [ebp].ghlx1
  1182.         mov ebx, [ebp].ghlx2
  1183.         mov esi, [ebp].ghlc1
  1184.         mov edx, [ebp].ghlc2
  1185.  
  1186.         cmp ebx, ecx
  1187.         jg ghlDraw
  1188.         xchg ebx, ecx
  1189.         xchg esi, edx
  1190.  
  1191. ghlDraw:
  1192.         mov [ebp].ghlc2, edx
  1193.  
  1194.         cmp ecx, 0
  1195.         jge ghlx1ok
  1196.         mov ecx, 0
  1197.  
  1198. ghlx1ok:
  1199.         cmp ecx, 320
  1200.         jge ghldone
  1201.  
  1202.         cmp ebx, 319
  1203.         jl ghlx2ok
  1204.         mov ebx, 319
  1205.  
  1206. ghlx2ok:
  1207.         cmp ebx, 0
  1208.         jl ghldone
  1209.  
  1210.  
  1211.         add eax, ecx
  1212.         add edi, eax
  1213.  
  1214.         sub ebx, ecx
  1215.         mov ecx, ebx
  1216.  
  1217.         jecxz ghlIHATESHORTJUMPS
  1218.  
  1219. ;        and ebx, 3
  1220. ;        shr ecx, 2
  1221.  
  1222.  
  1223.  
  1224.  
  1225.         mov eax, edx
  1226.         sub eax, esi
  1227.         shl eax, 8             ; dc *= 256
  1228.         xor edx, edx
  1229.  
  1230.         cmp eax, 0
  1231.         jl ghlNeg
  1232.         div ebx                 ; get dcdx
  1233.         jmp ghlGoOn
  1234.  
  1235. ghlIHATESHORTJUMPS:
  1236.         jmp ghlDone
  1237.  
  1238. ghlNeg:
  1239.         neg eax
  1240.         div ebx
  1241.         neg eax
  1242.  
  1243. ghlGoOn:
  1244.         mov edx, eax            ; edx = dcdx * 256
  1245.         mov ebx, esi            ; eax = c1
  1246.         shl ebx, 8              ; ebx *= 256
  1247.  
  1248.         ;mov esi, ecx
  1249.         ;and esi, 7
  1250.         ;shr ecx, 3
  1251.  
  1252.         cld
  1253.         align 4
  1254.  
  1255. ghlLoop:
  1256.         jcxz ghlMod
  1257.  
  1258.         mov [edi], bh
  1259.         inc edi
  1260.         add ebx, edx
  1261.  
  1262.         dec ecx
  1263.         jmp ghlLoop
  1264.  
  1265. ghlMod:
  1266.         ;mov ecx, esi
  1267.         ;rep stosb
  1268.  
  1269. ghlDone:
  1270.         pop edi
  1271.         pop esi
  1272.         pop ebp
  1273.  
  1274.         ret 20
  1275.  
  1276.  
  1277. gHline endp
  1278.  
  1279.  
  1280. ;----------------------------------------------------------------------------
  1281. ; void gpoly3(int x1, int y1, int c1, int x2, int y2, int c2, int x3, int y3,
  1282. ;               int c3);
  1283. ;----------------------------------------------------------------------------
  1284. ;
  1285. ; Draws a fully clipped gouraud shaded polygon at the given coordinates and
  1286. ; colors.  If you don't understand the concept behind gouraud shading, this
  1287. ; is not the place to learn.  Send email.
  1288. ;
  1289.  
  1290.  
  1291. gp3Stack struc
  1292.                 dd  ?,?,?       ; room for regs
  1293.                 dd  ?           ; caller
  1294.         gp3c3   dd  ?           ; c3
  1295.         gp3y3   dd  ?           ; y3
  1296.         gp3x3   dd  ?           ; x3
  1297.         gp3c2   dd  ?           ; c2
  1298.         gp3y2   dd  ?           ; y2
  1299.         gp3x2   dd  ?           ; x2
  1300.         gp3c1   dd  ?           ; c1
  1301.         gp3y1   dd  ?           ; y1
  1302.         gp3x1   dd  ?           ; x1
  1303.  
  1304. gp3Stack ends
  1305.  
  1306.         public gpoly3
  1307.  
  1308. gpoly3 proc
  1309.  
  1310.         push ebp
  1311.         push edi
  1312.         push esi
  1313.  
  1314.         mov ebp, esp
  1315.  
  1316.         mov eax, [ebp].gp3y1
  1317.         mov ebx, [ebp].gp3y2
  1318.         mov ecx, [ebp].gp3y3
  1319.  
  1320.         ; sort the points based on y values
  1321.  
  1322. gyComp1:
  1323.         cmp eax, ebx
  1324.         jg gy2top
  1325.  
  1326.         mov yTop, eax
  1327.         mov edx, [ebp].gp3x1
  1328.         mov xTop, edx
  1329.         mov edx, [ebp].gp3c1
  1330.         mov cTop, edx
  1331.  
  1332.         mov yBot, ebx
  1333.         mov edx, [ebp].gp3x2
  1334.         mov xBot, edx
  1335.         mov edx, [ebp].gp3c2
  1336.         mov cBot, edx
  1337.  
  1338.         jmp gyComp2
  1339.  
  1340. gy2top: mov yTop, ebx
  1341.         mov edx, [ebp].gp3x2
  1342.         mov xTop, edx
  1343.         mov edx, [ebp].gp3c2
  1344.         mov cTop, edx
  1345.  
  1346.         mov yBot, eax
  1347.         mov edx, [ebp].gp3x1
  1348.         mov xBot, edx
  1349.         mov edx, [ebp].gp3c1
  1350.         mov cBot, edx
  1351.  
  1352. gyComp2:
  1353.         cmp ecx, yTop
  1354.         jg gyTopOK
  1355.  
  1356.         mov yTop, ecx
  1357.         mov edx, [ebp].gp3x3
  1358.         mov xTop, edx
  1359.         mov edx, [ebp].gp3c3
  1360.         mov cTop, edx
  1361.  
  1362.         cmp eax, ebx
  1363.         jg gy2mid
  1364.  
  1365.         mov yMid, eax
  1366.         mov edx, [ebp].gp3x1
  1367.         mov xMid, edx
  1368.         mov edx, [ebp].gp3c1
  1369.         mov cMid, edx
  1370.  
  1371.         mov yBot, ebx
  1372.         mov edx, [ebp].gp3x2
  1373.         mov xBot, edx
  1374.         mov edx, [ebp].gp3c2
  1375.         mov cBot, edx
  1376.  
  1377.  
  1378.         jmp gyCompDone
  1379.  
  1380. gy2mid: mov yMid, ebx
  1381.         mov edx, [ebp].gp3x2
  1382.         mov xMid, edx
  1383.         mov edx, [ebp].gp3c2
  1384.         mov cMid, edx
  1385.  
  1386.         mov yBot, eax
  1387.         mov edx, [ebp].gp3x1
  1388.         mov xBot, edx
  1389.         mov edx, [ebp].gp3c1
  1390.         mov cBot, edx
  1391.  
  1392.         jmp gyCompDone
  1393.  
  1394. gyTopOK:
  1395.         cmp ecx, yBot
  1396.         jg gybBad
  1397.  
  1398.         mov yMid, ecx
  1399.         mov edx, [ebp].gp3x3
  1400.         mov xMid, edx
  1401.         mov edx, [ebp].gp3c3
  1402.         mov cMid, edx
  1403.  
  1404.         jmp gyCompDone
  1405.  
  1406. gybBad: mov eax, yBot
  1407.         mov ebx, xBot
  1408.         mov edx, cBot
  1409.  
  1410.         mov yMid, eax
  1411.         mov xMid, ebx
  1412.         mov cMid, edx
  1413.  
  1414.         mov yBot, ecx
  1415.         mov edx, [ebp].gp3x3
  1416.         mov xBot, edx
  1417.         mov edx, [ebp].gp3c3
  1418.         mov cBot, edx
  1419.  
  1420.  
  1421. gyCompDone:
  1422.  
  1423.         mov eax, yTop
  1424.         mov ebx, yBot
  1425.         cmp eax, 199
  1426.         jg gfillDone
  1427.         cmp ebx, 0
  1428.         jl gfillDone
  1429.  
  1430.         ; now calculate the x values at each scanline for the longest side.
  1431.  
  1432.         mov eax, xBot
  1433.         mov ebx, xTop
  1434.         sub eax, ebx
  1435.         shl eax, 16
  1436.  
  1437.         mov ecx, yBot
  1438.         mov edx, yTop
  1439.         sub ecx, edx
  1440.  
  1441.         jecxz gedge1Horz         ; skip the div if denominator = 0
  1442.         cmp eax, 0
  1443.         jge gedge1Pos
  1444.  
  1445.         neg eax
  1446.         xor edx, edx
  1447.         div ecx
  1448.         neg eax
  1449.  
  1450.         jmp gedge1Continue
  1451.  
  1452. gedge1Horz:
  1453.         ;xor eax, eax
  1454.         ;xor edx, edx
  1455.         ;jmp gedge1Continue
  1456.  
  1457.         jmp gedge2Start
  1458.  
  1459. gedge1Pos:
  1460.         xor edx, edx
  1461.         div ecx
  1462.  
  1463. gedge1Continue:
  1464.         mov ecx, yBot
  1465.         mov ebx, yTop
  1466.         sub ecx, ebx
  1467.  
  1468.         shl ebx, 2
  1469.         lea edi, lEdge
  1470.         add edi, ebx
  1471.  
  1472.         xor ebx, ebx
  1473.         mov edx, xTop
  1474.         mov esi, yTop
  1475.  
  1476.         align 4
  1477.  
  1478. gedge1Loop:
  1479.  
  1480.         cmp esi, 0
  1481.         jl gskipThisLine1
  1482.         cmp esi, 199
  1483.         jg gedge2Start
  1484.  
  1485.         ror ebx, 16
  1486.         add dx, bx
  1487.         movsx edx, dx
  1488.         rol ebx, 16
  1489.         movzx ebx, bx
  1490.         mov [edi], edx
  1491.  
  1492. gskipThisLine1:
  1493.         add ebx, eax
  1494.         add edi, 4
  1495.         inc esi
  1496.         dec ecx
  1497.         jns gedge1Loop
  1498.  
  1499.         ; calculate x values for next side
  1500.  
  1501. gedge2Start:
  1502.         mov eax, xBot
  1503.         mov ebx, xMid
  1504.         sub eax, ebx
  1505.         shl eax, 16
  1506.  
  1507.         mov ecx, yBot
  1508.         mov edx, yMid
  1509.         sub ecx, edx
  1510.  
  1511.         jecxz gedge2Horz
  1512.         cmp eax, 0
  1513.         jge gedge2Pos
  1514.  
  1515.         neg eax
  1516.         xor edx, edx
  1517.         div ecx
  1518.         neg eax
  1519.         jmp gedge2Continue
  1520.  
  1521. gedge2Horz:
  1522.         ;xor eax, eax
  1523.         ;xor edx, edx
  1524.         ;jmp gedge2Continue
  1525.         jmp gedge3Start
  1526.  
  1527. gedge2Pos:
  1528.         xor edx, edx
  1529.         div ecx
  1530.  
  1531. gedge2Continue:
  1532.         mov ecx, yBot
  1533.         mov ebx, yMid
  1534.         sub ecx, ebx
  1535.  
  1536.         shl ebx, 2
  1537.         lea edi, rEdge
  1538.         add edi, ebx
  1539.  
  1540.         xor ebx, ebx
  1541.         mov edx, xMid
  1542.         mov esi, yMid
  1543.  
  1544.         align 4
  1545.  
  1546. gedge2Loop:
  1547.  
  1548.         cmp esi, 0
  1549.         jl gskipThisLine2
  1550.         cmp esi, 199
  1551.         jg gedge3Start
  1552.  
  1553.         ror ebx, 16
  1554.         add dx, bx
  1555.         movsx edx, dx
  1556.         rol ebx, 16
  1557.         movzx ebx, bx
  1558.         mov [edi], edx
  1559.  
  1560. gskipThisLine2:
  1561.         add ebx, eax
  1562.         add edi, 4
  1563.         inc esi
  1564.         dec ecx
  1565.         jns gedge2Loop
  1566.  
  1567.         ; calculate x values for last side
  1568.  
  1569. gedge3Start:
  1570.         mov eax, xMid
  1571.         mov ebx, xTop
  1572.         sub eax, ebx
  1573.         shl eax, 16
  1574.  
  1575.         mov ecx, yMid
  1576.         mov edx, yTop
  1577.         sub ecx, edx
  1578.  
  1579.         jecxz gedge3Horz
  1580.         cmp eax, 0
  1581.         jge gedge3Pos
  1582.  
  1583.         neg eax
  1584.         xor edx, edx
  1585.         div ecx
  1586.         neg eax
  1587.  
  1588.         jmp gedge3Continue
  1589.  
  1590. gedge3Horz:
  1591.         ;xor eax, eax            ; zero ratio
  1592.         ;xor edx, edx
  1593.         ;jmp gedge3Continue
  1594.         jmp gcolorStartc
  1595.  
  1596. gedge3Pos:
  1597.         xor edx, edx
  1598.         div ecx
  1599.  
  1600. gedge3Continue:
  1601.         mov ecx, yMid
  1602.         mov ebx, yTop
  1603.         sub ecx, ebx
  1604.  
  1605.         shl ebx, 2
  1606.         lea edi, rEdge
  1607.         add edi, ebx
  1608.  
  1609.         xor ebx, ebx
  1610.         mov edx, xTop
  1611.         mov esi, yTop
  1612.  
  1613.         align 4
  1614.  
  1615. gedge3Loop:
  1616.  
  1617.         cmp esi, 0
  1618.         jl gskipThisLine3
  1619.         cmp esi, 199
  1620.         jg gcolorStartc
  1621.  
  1622.         ror ebx, 16
  1623.         add dx, bx
  1624.         movsx edx, dx
  1625.         rol ebx, 16
  1626.         movzx ebx, bx
  1627.         mov [edi], edx
  1628.  
  1629. gskipThisLine3:
  1630.         add ebx, eax
  1631.         add edi, 4
  1632.         inc esi
  1633.         dec ecx
  1634.         jns gedge3Loop
  1635.  
  1636. gcolorStartc:
  1637.  
  1638.         ; now calculate the color values at each scanline for the longest side.
  1639.  
  1640.         mov eax, cBot
  1641.         mov ebx, cTop
  1642.         sub eax, ebx
  1643.         shl eax, 16
  1644.  
  1645.         mov ecx, yBot
  1646.         mov edx, yTop
  1647.         sub ecx, edx
  1648.  
  1649.         jecxz gedge1Horzc         ; skip the div if denominator = 0
  1650.         cmp eax, 0
  1651.         jge gedge1Posc
  1652.  
  1653.         neg eax
  1654.         xor edx, edx
  1655.         div ecx
  1656.         neg eax
  1657.  
  1658.         jmp gedge1Continuec
  1659.  
  1660. gedge1Horzc:
  1661.         ;xor eax, eax
  1662.         ;xor edx, edx
  1663.         ;jmp gedge1Continuec
  1664.  
  1665.         jmp gedge2Startc
  1666.  
  1667. gedge1Posc:
  1668.         xor edx, edx
  1669.         div ecx
  1670.  
  1671. gedge1Continuec:
  1672.         mov ecx, yBot
  1673.         mov ebx, yTop
  1674.         sub ecx, ebx
  1675.  
  1676.         shl ebx, 2
  1677.         lea edi, lColor
  1678.         add edi, ebx
  1679.  
  1680.         xor ebx, ebx
  1681.         mov edx, cTop
  1682.         mov esi, yTop
  1683.  
  1684.         align 4
  1685.  
  1686. gedge1Loopc:
  1687.  
  1688.         cmp esi, 0
  1689.         jl gskipThisLine1c
  1690.         cmp esi, 199
  1691.         jg gedge2Startc
  1692.  
  1693.         ror ebx, 16
  1694.         add dx, bx
  1695.         movsx edx, dx
  1696.         rol ebx, 16
  1697.         movzx ebx, bx
  1698.         mov [edi], edx
  1699.  
  1700. gskipThisLine1c:
  1701.         add ebx, eax
  1702.         add edi, 4
  1703.         inc esi
  1704.         dec ecx
  1705.         jns gedge1Loopc
  1706.  
  1707.         ; calculate x values for next side
  1708.  
  1709. gedge2Startc:
  1710.         mov eax, cBot
  1711.         mov ebx, cMid
  1712.         sub eax, ebx
  1713.         shl eax, 16
  1714.  
  1715.         mov ecx, yBot
  1716.         mov edx, yMid
  1717.         sub ecx, edx
  1718.  
  1719.         jecxz gedge2Horzc
  1720.         cmp eax, 0
  1721.         jge gedge2Posc
  1722.  
  1723.         neg eax
  1724.         xor edx, edx
  1725.         div ecx
  1726.         neg eax
  1727.         jmp gedge2Continuec
  1728.  
  1729. gedge2Horzc:
  1730.         ;xor eax, eax
  1731.         ;xor edx, edx
  1732.         ;jmp gedge2Continuec
  1733.         jmp gedge3Startc
  1734.  
  1735. gedge2Posc:
  1736.         xor edx, edx
  1737.         div ecx
  1738.  
  1739. gedge2Continuec:
  1740.         mov ecx, yBot
  1741.         mov ebx, yMid
  1742.         sub ecx, ebx
  1743.  
  1744.         shl ebx, 2
  1745.         lea edi, rColor
  1746.         add edi, ebx
  1747.  
  1748.         xor ebx, ebx
  1749.         mov edx, cMid
  1750.         mov esi, yMid
  1751.  
  1752.         align 4
  1753.  
  1754. gedge2Loopc:
  1755.  
  1756.         cmp esi, 0
  1757.         jl gskipThisLine2c
  1758.         cmp esi, 199
  1759.         jg gedge3Startc
  1760.  
  1761.         ror ebx, 16
  1762.         add dx, bx
  1763.         movsx edx, dx
  1764.         rol ebx, 16
  1765.         movzx ebx, bx
  1766.         mov [edi], edx
  1767.  
  1768. gskipThisLine2c:
  1769.         add ebx, eax
  1770.         add edi, 4
  1771.         inc esi
  1772.         dec ecx
  1773.         jns gedge2Loopc
  1774.  
  1775.         ; calculate x values for last side
  1776.  
  1777. gedge3Startc:
  1778.         mov eax, cMid
  1779.         mov ebx, cTop
  1780.         sub eax, ebx
  1781.         shl eax, 16
  1782.  
  1783.         mov ecx, yMid
  1784.         mov edx, yTop
  1785.         sub ecx, edx
  1786.  
  1787.         jecxz gedge3Horzc
  1788.         cmp eax, 0
  1789.         jge gedge3Posc
  1790.  
  1791.         neg eax
  1792.         xor edx, edx
  1793.         div ecx
  1794.         neg eax
  1795.  
  1796.         jmp gedge3Continuec
  1797.  
  1798. gedge3Horzc:
  1799.         ;xor eax, eax            ; zero ratio
  1800.         ;xor edx, edx
  1801.         ;jmp gedge3Continuec
  1802.         jmp gfillStart
  1803.  
  1804. gedge3Posc:
  1805.         xor edx, edx
  1806.         div ecx
  1807.  
  1808. gedge3Continuec:
  1809.         mov ecx, yMid
  1810.         mov ebx, yTop
  1811.         sub ecx, ebx
  1812.  
  1813.         shl ebx, 2
  1814.         lea edi, rColor
  1815.         add edi, ebx
  1816.  
  1817.         xor ebx, ebx
  1818.         mov edx, cTop
  1819.         mov esi, yTop
  1820.  
  1821.         align 4
  1822.  
  1823. gedge3Loopc:
  1824.  
  1825.         cmp esi, 0
  1826.         jl gskipThisLine3c
  1827.         cmp esi, 199
  1828.         jg gfillStart
  1829.  
  1830.         ror ebx, 16
  1831.         add dx, bx
  1832.         movsx edx, dx
  1833.         rol ebx, 16
  1834.         movzx ebx, bx
  1835.         mov [edi], edx
  1836.  
  1837. gskipThisLine3c:
  1838.         add ebx, eax
  1839.         add edi, 4
  1840.         inc esi
  1841.         dec ecx
  1842.         jns gedge3Loopc
  1843.  
  1844.  
  1845.         ; time to fill...
  1846.  
  1847. gfillStart:
  1848.  
  1849.         mov eax, yTop
  1850.         mov ebx, yBot
  1851.  
  1852.         cmp eax, 0
  1853.         jge gcheckBot
  1854.         xor eax, eax
  1855.         mov yTop, eax
  1856.  
  1857. gcheckBot:
  1858.         cmp ebx, 199
  1859.         jle gfillNOW
  1860.         mov ebx, 199
  1861.         mov yBot, ebx
  1862.  
  1863. gfillNOW:
  1864.         lea esi, lEdge
  1865.         lea edi, rEdge
  1866.  
  1867.         lea eax, lColor
  1868.         lea edx, rColor
  1869.  
  1870.         mov ecx, yTop
  1871.         mov ebx, yBot
  1872.         shl ecx, 2
  1873.  
  1874.         add esi, ecx
  1875.         add edi, ecx
  1876.         add eax, ecx
  1877.         add edx, ecx
  1878.  
  1879.         shr ecx, 2
  1880.  
  1881.         align 4
  1882.  
  1883. gfillME: push ecx
  1884.  
  1885.  
  1886. grhlDraw:
  1887.  
  1888.         cmp ecx, 319
  1889.         jg gnextLine
  1890.  
  1891.         cmp ebx, 0
  1892.         jl gnextLine
  1893.  
  1894. gcheckX2:
  1895.         cmp ebx, 319
  1896.         jle gcheckX1
  1897.         mov ebx, 319
  1898.  
  1899. gcheckX1:
  1900.         cmp ecx, 0
  1901.         jge gx1OKToo
  1902.         xor ecx, ecx
  1903.  
  1904. gx1OKToo:
  1905.         push esi
  1906.         push eax
  1907.         push edi
  1908.         push edx
  1909.  
  1910.         push [esi]
  1911.         push [eax]
  1912.         push [edi]
  1913.         push [edx]
  1914.         push ecx
  1915.  
  1916.         call gHline
  1917.  
  1918.         pop edx
  1919.         pop edi
  1920.         pop eax
  1921.         pop esi
  1922.  
  1923. gnextLine:
  1924.         pop ecx
  1925.  
  1926.         add esi, 4
  1927.         add edi, 4
  1928.         add eax, 4
  1929.         add edx, 4
  1930.         inc ecx
  1931.         cmp ecx, yBot
  1932.         jg gfillDone
  1933.         jmp gfillME
  1934.  
  1935. gfillDone:
  1936.  
  1937.         pop esi
  1938.         pop edi
  1939.         pop ebp
  1940.  
  1941.         ret 36
  1942.  
  1943. gpoly3 endp
  1944.  
  1945.  
  1946. ;--------------------------------------------------------------------
  1947. ; void tDrawBitmap(char *image, int x, int y, int width, int height);
  1948. ;--------------------------------------------------------------------
  1949. ;
  1950. ; draws a bitmapt to the screen, with color 0 transparent.  Full clipping
  1951. ; is done as an added bonus...
  1952. ;
  1953.  
  1954. tdbStack STRUC
  1955.  
  1956.                         dd  ?,?,?       ; ebp, esi, edi
  1957.                         dd  ?           ; caller
  1958.         tdbHeight       dd  ?
  1959.         tdbWidth        dd  ?
  1960.         tdbY            dd  ?
  1961.         tdbX            dd  ?
  1962.         tdbImage        dd  ?
  1963.  
  1964. tdbStack ENDS
  1965.  
  1966.         public tDrawBitmap
  1967.  
  1968. tDrawBitmap proc
  1969.  
  1970.         push edi
  1971.         push esi
  1972.         push ebp
  1973.  
  1974.         mov ebp, esp
  1975.  
  1976.         mov eax, 0
  1977.         mov sPos, eax
  1978.         mov xOffset, 0
  1979.         mov yOffset, 0
  1980.  
  1981.         mov esi, [ebp].tdbImage
  1982.         mov edi, curPage
  1983.         mov ecx, [ebp].tdbY
  1984.         mov eax, 320
  1985.         mul ecx
  1986.         mov edx, [ebp].tdbX
  1987.         add eax, edx
  1988.         mov dPos, eax
  1989.  
  1990.         mov ebx, [ebp].tdbWidth
  1991.         mov eax, [ebp].tdbHeight
  1992.         mov oWidth, ebx
  1993.         mov nWidth, ebx
  1994.         mov oHeight, eax
  1995.         mov nHeight, eax
  1996.  
  1997.         ; clipping action...
  1998.  
  1999.         cmp edx, 0
  2000.         jl tdbXNeg
  2001.  
  2002. tdbCheckY:
  2003.         cmp ecx, 0
  2004.         jl tdbYNeg
  2005.  
  2006.         jmp tdbContinue
  2007.  
  2008. tdbXNeg:
  2009.         neg edx
  2010.         cmp edx, ebx
  2011.         jg tdbDone              ; bitmap is off screen if -x > width
  2012.         mov xOffset, edx        ; store the offset
  2013.         neg edx                 ; back to negative...
  2014.         add nWidth, edx
  2015.  
  2016.         jmp tdbCheckY
  2017.  
  2018. tdbYNeg:
  2019.         neg ecx
  2020.         cmp ecx, eax
  2021.         jge tdbDone              ; bitmap is off screen if -y > height
  2022.         ;neg ecx
  2023.         ;add ecx, eax
  2024.         sub nHeight, ecx
  2025.         inc ecx
  2026.  
  2027. tdbFixY:
  2028.         dec ecx
  2029.         cmp ecx, 0
  2030.         jle tdbContinue
  2031.         add dPos, 320           ; go to next line on screen
  2032.         add sPos, ebx           ; go to next line in source
  2033.         jmp tdbFixY
  2034.  
  2035. tdbContinue:
  2036.  
  2037.         mov ecx, [ebp].tdbY     ; recharge ecx
  2038.  
  2039.         cmp ecx, 200 ;
  2040.         jg tdbDone
  2041.  
  2042.         cmp edx, 320 ;
  2043.         jg tdbDone
  2044.  
  2045.         add ebx, edx
  2046.         cmp ebx, 320 ;
  2047.         jg tdbXTooBig
  2048.  
  2049. tdbCheckY2:
  2050.         add eax, ecx
  2051.         cmp eax, 200 ;
  2052.         ;cmp nHeight, 200
  2053.         jge tdbYTooBig
  2054.  
  2055.         jmp tdbClipDone
  2056.  
  2057. tdbXTooBig:
  2058.         mov nWidth, ebx
  2059.         cmp edx, 0
  2060.         jge tdbXPos
  2061.  
  2062.         cmp nWidth, 320
  2063.         jl tdbClipDone
  2064.         mov nWidth, 320
  2065.         jmp tdbCheckY2
  2066.  
  2067.         ;mov ebx, 320
  2068.         ;sub ebx, edx
  2069.         ;cmp ebx, 320
  2070.         ;jl tdbXTooBig2
  2071.         ;mov ebx, 320
  2072.  
  2073. tdbXPos:
  2074.         mov ebx, 320
  2075.         sub ebx, edx
  2076.         mov nWidth, ebx
  2077.         jmp tdbCheckY2
  2078.  
  2079. tdbXTooBig2:
  2080.         ;mov nWidth, ebx
  2081.         ;jmp tdbCheckY2
  2082.  
  2083.         ;sub edx, 320 ;
  2084.         ;sub ebx, edx            ; get new 'width'
  2085.         ;mov nWidth, ebx
  2086.         ;jmp tdbCheckY2
  2087.  
  2088. tdbYTooBig:
  2089.         cmp ecx, 0
  2090.         jge tdbYPos
  2091.  
  2092.         cmp nHeight, 200
  2093.         jl tdbClipDone
  2094.         mov nHeight, 200
  2095.         jmp tdbClipDone
  2096.         ;cmp eax, 0
  2097.         ;jg tdbYTooBigPos
  2098.         ;mov eax, 200
  2099.         ;sub eax, ecx
  2100.         ;cmp eax, 200
  2101.         ;jl tdbYTooBig3
  2102.         ;mov eax, 200
  2103.         ;jmp tdbYTooBig3
  2104.  
  2105. tdbYPos:
  2106.         mov eax, 200
  2107.         sub eax, ecx
  2108.         mov nHeight, eax
  2109.         jmp tdbClipDone
  2110.  
  2111.  
  2112. tdbYTooBig3:
  2113.         ;mov nHeight, eax
  2114.         ;jmp tdbClipDone
  2115.  
  2116.         ;sub ecx, 200 ;
  2117.         ;sub eax, ecx            ; get new 'height'
  2118.         ;mov nHeight, eax
  2119.         ;jmp tdbClipDone
  2120.  
  2121. tdbClipDone:
  2122.  
  2123.         mov ecx, nHeight            ; get 'height'
  2124.         cld
  2125.         mov edx, xOffset
  2126.         add sPos, edx
  2127.         add dPos, edx
  2128.  
  2129.         align 4
  2130.  
  2131. tdbDrawLoop:
  2132.         mov esi, [ebp].tdbImage
  2133.         add esi, sPos
  2134.  
  2135.         mov edi, curPage
  2136.         add edi, dPos
  2137.  
  2138.         mov ebx, ecx
  2139.         mov ecx, nWidth
  2140.         mov edx, xOffset
  2141.         ;sub ecx, edx
  2142.  
  2143.         align 4
  2144.  
  2145. tdbRowLoop:
  2146.  
  2147.         cmp ecx, 4
  2148.         jl tdbMod
  2149.  
  2150.         lodsd
  2151.  
  2152.         test al, 0FFh
  2153.         jz tdbPix2
  2154.         stosb
  2155.         dec edi
  2156.  
  2157. tdbPix2:
  2158.         inc edi
  2159.         shr eax, 8
  2160.         test al, 0FFh
  2161.         jz tdbPix3
  2162.         stosb
  2163.         dec edi
  2164.  
  2165. tdbPix3:
  2166.         inc edi
  2167.         shr eax, 8
  2168.         test al, 0FFh
  2169.         jz tdbPix4
  2170.         stosb
  2171.         dec edi
  2172.  
  2173. tdbPix4:
  2174.         inc edi
  2175.         shr eax, 8
  2176.         test al, 0FFh
  2177.         jz tdbNextDW
  2178.         stosb
  2179.         dec edi
  2180.  
  2181. tdbNextDW:
  2182.         inc edi
  2183.         sub ecx, 4
  2184.         jmp tdbRowLoop
  2185.  
  2186. tdbMod:
  2187.         jecxz tdbRowDone
  2188.         lodsb
  2189.         test al, 0FFh
  2190.         jz tdbMod2
  2191.         stosb
  2192.         dec edi
  2193.  
  2194. tdbMod2:
  2195.         inc edi
  2196.         dec ecx
  2197.         jecxz tdbRowDone
  2198.         lodsb
  2199.         test al, 0FFh
  2200.         jz tdbMod3
  2201.         stosb
  2202.         dec edi
  2203.  
  2204. tdbMod3:
  2205.         inc edi
  2206.         dec ecx
  2207.         jecxz tdbRowDone
  2208.         lodsb
  2209.         test al, 0FFh
  2210.         jz tdbRowDone
  2211.         stosb
  2212.         dec edi
  2213.  
  2214. tdbRowDone:
  2215.         inc edi
  2216.         mov ecx, ebx
  2217.         dec ecx
  2218.         mov ebx, oWidth
  2219.         add sPos, ebx
  2220.         add dPos, 320
  2221. ;        mov ebx, xOffset
  2222. ;        add dPos, ebx
  2223. ;        add sPos, ebx
  2224.  
  2225.         cmp ecx, 0
  2226.         jle tdbDone
  2227.  
  2228.         ;jecxz tdbDone
  2229.         jmp tdbDrawLoop
  2230.  
  2231. tdbDone:
  2232.  
  2233.         pop ebp
  2234.         pop esi
  2235.         pop edi
  2236.  
  2237.         ret 20
  2238.  
  2239.  
  2240. tDrawBitmap endp
  2241.  
  2242.  
  2243. ;-------------------------------------------------------------------
  2244. ; void drawBitmap(char *image, int x, int y, int width, int height);
  2245. ;-------------------------------------------------------------------
  2246. ;
  2247. ; draws a bitmap to the screen.  Full clipping once again...
  2248. ;
  2249.  
  2250.  
  2251. dbStack STRUC
  2252.  
  2253.                         dd  ?,?,?       ; ebp, esi, edi
  2254.                         dd  ?           ; caller
  2255.         dbHeight       dd  ?
  2256.         dbWidth        dd  ?
  2257.         dbY            dd  ?
  2258.         dbX            dd  ?
  2259.         dbImage        dd  ?
  2260.  
  2261. dbStack ENDS
  2262.  
  2263.         public drawBitmap
  2264.  
  2265. drawBitmap proc
  2266.  
  2267.         push edi
  2268.         push esi
  2269.         push ebp
  2270.  
  2271.         mov ebp, esp
  2272.  
  2273.         mov eax, 0
  2274.         mov sPos, eax
  2275.         mov xOffset, 0
  2276.         mov yOffset, 0
  2277.  
  2278.         mov esi, [ebp].dbImage
  2279.         mov edi, curPage
  2280.         mov ecx, [ebp].dbY
  2281.         mov eax, 320
  2282.         mul ecx
  2283.         mov edx, [ebp].dbX
  2284.         add eax, edx
  2285.         mov dPos, eax
  2286.  
  2287.         mov ebx, [ebp].dbWidth
  2288.         mov eax, [ebp].dbHeight
  2289.         mov oWidth, ebx
  2290.         mov nWidth, ebx
  2291.         mov oHeight, eax
  2292.         mov nHeight, eax
  2293.  
  2294.         ; clipping action...
  2295.  
  2296.         cmp edx, 0
  2297.         jl dbXNeg
  2298.  
  2299. dbCheckY:
  2300.         cmp ecx, 0
  2301.         jl dbYNeg
  2302.  
  2303.         jmp dbContinue
  2304.  
  2305. dbXNeg:
  2306.         neg edx
  2307.         cmp edx, ebx
  2308.         jg dbDone              ; bitmap is off screen if -x > width
  2309.         mov xOffset, edx        ; store the offset
  2310.         neg edx                 ; back to negative...
  2311.         add nWidth, edx
  2312.  
  2313.         jmp dbCheckY
  2314.  
  2315. dbYNeg:
  2316.         neg ecx
  2317.         cmp ecx, eax
  2318.         jge dbDone              ; bitmap is off screen if -y > height
  2319.         ;neg ecx
  2320.         ;add ecx, eax
  2321.         sub nHeight, ecx
  2322.         inc ecx
  2323.  
  2324. dbFixY:
  2325.         dec ecx
  2326.         cmp ecx, 0
  2327.         jle dbContinue
  2328.         add dPos, 320           ; go to next line on screen
  2329.         add sPos, ebx           ; go to next line in source
  2330.         jmp dbFixY
  2331.  
  2332. dbContinue:
  2333.  
  2334.         mov ecx, [ebp].dbY     ; recharge ecx
  2335.  
  2336.         cmp ecx, 200 ;
  2337.         jg dbDone
  2338.  
  2339.         cmp edx, 320 ;
  2340.         jg dbDone
  2341.  
  2342.         add ebx, edx
  2343.         cmp ebx, 320 ;
  2344.         jg dbXTooBig
  2345.  
  2346. dbCheckY2:
  2347.         add eax, ecx
  2348.         cmp eax, 200 ;
  2349.         ;cmp nHeight, 200
  2350.         jge dbYTooBig
  2351.  
  2352.         jmp dbClipDone
  2353.  
  2354. dbXTooBig:
  2355.         mov nWidth, ebx
  2356.         cmp edx, 0
  2357.         jge dbXPos
  2358.  
  2359.         cmp nWidth, 320
  2360.         jl dbClipDone
  2361.         mov nWidth, 320
  2362.         jmp dbCheckY2
  2363.  
  2364.         ;mov ebx, 320
  2365.         ;sub ebx, edx
  2366.         ;cmp ebx, 320
  2367.         ;jl dbXTooBig2
  2368.         ;mov ebx, 320
  2369.  
  2370. dbXPos:
  2371.         mov ebx, 320
  2372.         sub ebx, edx
  2373.         mov nWidth, ebx
  2374.         jmp dbCheckY2
  2375.  
  2376. dbXTooBig2:
  2377.         ;mov nWidth, ebx
  2378.         ;jmp dbCheckY2
  2379.  
  2380.         ;sub edx, 320 ;
  2381.         ;sub ebx, edx            ; get new 'width'
  2382.         ;mov nWidth, ebx
  2383.         ;jmp dbCheckY2
  2384.  
  2385. dbYTooBig:
  2386.         cmp ecx, 0
  2387.         jge dbYPos
  2388.  
  2389.         cmp nHeight, 200
  2390.         jl dbClipDone
  2391.         mov nHeight, 200
  2392.         jmp dbclipDone
  2393.         ;cmp eax, 0
  2394.         ;jg dbYTooBigPos
  2395.         ;mov eax, 200
  2396.         ;sub eax, ecx
  2397.         ;cmp eax, 200
  2398.         ;jl dbYTooBig3
  2399.         ;mov eax, 200
  2400.         ;jmp dbYTooBig3
  2401.  
  2402. dbYPos:
  2403.         mov eax, 200
  2404.         sub eax, ecx
  2405.         mov nHeight, eax
  2406.         jmp dbclipDone
  2407.  
  2408.  
  2409. dbYTooBig3:
  2410.         ;mov nHeight, eax
  2411.         ;jmp dbClipDone
  2412.  
  2413.         ;sub ecx, 200 ;
  2414.         ;sub eax, ecx            ; get new 'height'
  2415.         ;mov nHeight, eax
  2416.         ;jmp dbClipDone
  2417.  
  2418. dbClipDone:
  2419.  
  2420.         mov ecx, nHeight            ; get 'height'
  2421.         cld
  2422.         mov edx, xOffset
  2423.         add sPos, edx
  2424.         add dPos, edx
  2425.  
  2426.         align 4
  2427.  
  2428. dbDrawLoop:
  2429.         mov esi, [ebp].dbImage
  2430.         add esi, sPos
  2431.  
  2432.         mov edi, curPage
  2433.         add edi, dPos
  2434.  
  2435.         mov ebx, ecx
  2436.         mov ecx, nWidth
  2437.         mov edx, xOffset
  2438.         ;sub ecx, edx
  2439.  
  2440. dbRowLoop:
  2441.  
  2442.         mov edx, ecx
  2443.         shr ecx, 2
  2444.         and edx, 3
  2445.  
  2446.         cmp ecx, 0
  2447.         jle dbMod
  2448.  
  2449.         rep movsd
  2450.  
  2451. dbMod:
  2452.         mov ecx, edx
  2453.         rep movsb
  2454.  
  2455.  
  2456. dbRowDone:
  2457.         mov ecx, ebx
  2458.         dec ecx
  2459.         mov ebx, oWidth
  2460.         add sPos, ebx
  2461.         add dPos, 320
  2462. ;        mov ebx, xOffset
  2463. ;        add dPos, ebx
  2464. ;        add sPos, ebx
  2465.  
  2466.         cmp ecx, 0
  2467.         jle dbDone
  2468.  
  2469.         ;jecxz dbDone
  2470.         jmp dbDrawLoop
  2471.  
  2472. dbDone:
  2473.  
  2474.         pop ebp
  2475.         pop esi
  2476.         pop edi
  2477.  
  2478.         ret 20
  2479.  
  2480.  
  2481. drawBitmap endp
  2482.  
  2483. ; NOTE: clearing the ENTIRE z-buffer is a very slow way of doing things.  I
  2484. ; have implemented a system of z-buffer checking that eliminates this time
  2485. ; consuming step, given a certain range of background colors.  In the hline
  2486. ; routines, I do a TEST on screen location I am about to write to.  Right now,
  2487. ; I draw to the screen without checking the z-buffer if the current pixel is
  2488. ; color 0.  This can easily be modified to give an acceptable range of
  2489. ; background colors.  For example, if you want to have 16 background colors,
  2490. ; replace the test BYTE PTR [edi], 0FFh with test BYTE PTR [edi], 0F0h.  This
  2491. ; will eliminate z-buffer checking for all colors < 16, so you would be free
  2492. ; to use colors 0-15 in your background.  If all of this is too confusing,
  2493. ; remove the test/jz pair from the inner loop and just call clearZBuf before
  2494. ; you start drawing a new frame.
  2495.  
  2496.  
  2497.         public clearZBuf
  2498.  
  2499. clearZBuf proc
  2500.  
  2501.         push edi
  2502.  
  2503.         mov edi, zBuf           ; get address of z-buffer
  2504.         mov ecx, 32000          ; store 32000 dwords (128000 bytes)
  2505.         mov eax, 07FFF7FFFh     ; fill two words at once with 7fffh (32767,
  2506.                                 ; greatest 16 bit signed quantity)
  2507.  
  2508.         cld                     ; clear direction flag for forward writes
  2509.         rep stosd               ; and...GO
  2510.  
  2511.         pop edi
  2512.  
  2513.         ret
  2514.  
  2515. clearZBuf endp
  2516.  
  2517.  
  2518. ; OK, here is where the nice, commented code starts ;)  Everything up to this
  2519. ; point is either very basic, or is extended in the following four procedures.
  2520. ; Everything up until this point is also fairly unoptimized, I spent all my
  2521. ; time optimizing the code I planned on using.  The most noticable difference
  2522. ; in the z-buffered polygon routines is faster scan conversion.
  2523.  
  2524.  
  2525. zhlStack struc
  2526.  
  2527.                 dd ?,?,?        ; ebp esi edi
  2528.                 dd ?            ; caller
  2529.         zhlc    dd ?            ; color
  2530.         zhly    dd ?            ; y
  2531.         zhlz2   dd ?            ; z2
  2532.         zhlx2   dd ?            ; x2
  2533.         zhlz1   dd ?            ; z1
  2534.         zhlx1   dd ?            ; x1
  2535.  
  2536. zhlStack ends
  2537.  
  2538.         public zHline
  2539.  
  2540. zHline proc     ; zbuffered hline routine
  2541.  
  2542.         push ebp
  2543.         push esi
  2544.         push edi
  2545.         mov ebp, esp
  2546.  
  2547.         mov eax, [ebp].zhlc     ; get color
  2548.         mov cTop, eax           ; store the color (kludgy? I don't care ;))
  2549.  
  2550.         mov eax, [ebp].zhly     ; get y value
  2551.  
  2552.         lea eax, [eax + eax * 4]        ; use lea to do a fast multiply
  2553.         shl eax, 6                      ; now eax = eax * 320
  2554.  
  2555.         mov edi, curPage        ; get address of current page
  2556.  
  2557.         mov ecx, [ebp].zhlx1    ; load x and z values
  2558.         mov ebx, [ebp].zhlx2
  2559.         mov esi, [ebp].zhlz1
  2560.         mov edx, [ebp].zhlz2
  2561.  
  2562.         movsx ecx, cx           ; sign extend 16 bit values into 32 bit regs
  2563.         movsx ebx, bx
  2564.         movsx esi, si
  2565.         movsx edx, dx
  2566.  
  2567.         cmp ebx, ecx            ; make sure x2 > x1
  2568.         jg zhlDraw              ; if so, go ahead
  2569.         xchg ebx, ecx           ; if not, switcharoo...
  2570.         xchg esi, edx
  2571.  
  2572. zhlDraw:
  2573.         mov [ebp].zhlz2, edx    ; save the new z2 value to free a register
  2574.  
  2575.         cmp ecx, 0              ; clip the left end of the line
  2576.         jge zhlx1ok
  2577.         mov ecx, 0
  2578.  
  2579. zhlx1ok:
  2580.         cmp ecx, 320            ; see if the left end is off the right side
  2581.         jge zhldone             ; of the screen
  2582.  
  2583.         cmp ebx, 319            ; clip the right end of the line
  2584.         jl zhlx2ok
  2585.         mov ebx, 319
  2586.  
  2587. zhlx2ok:
  2588.         cmp ebx, 0              ; see if the right end is off the left side
  2589.         jl zhldone              ; of the screen
  2590.  
  2591.         mov ebp, zBuf           ; get the z-buffer address
  2592.  
  2593.         add eax, ecx            ; calculate starting offset, y * width + x1
  2594.         add edi, eax            ; starting screen address
  2595.         shl eax, 1              ; * 2 for words
  2596.         add ebp, eax            ; starting z-buffer address
  2597.         shr eax, 1              ; / 2 to give us bytes again
  2598.  
  2599.         ; here I used to check to see if both endpoints of the line were
  2600.         ; obscured by other polygons.  This may speed things up if you have
  2601.         ; a lot of planes stacked on top of each other, but it may also
  2602.         ; make intersecting planes display incorrectly
  2603.  
  2604.         ;cmp esi, [ebp + ecx * 2]        ; see if the first endpoint is visible
  2605.         ;jl zhlPartVis
  2606.  
  2607.         ;cmp edx, [ebp + ebx * 2]        ; test the 2nd if the first is invis
  2608.         ;jg zhlDone
  2609.  
  2610. zhlPartVis:
  2611.         sub ebx, ecx    ; get # of pix to draw
  2612.         mov ecx, ebx
  2613.  
  2614.         jecxz zhlIHATESHORTJUMPS
  2615.  
  2616.         mov eax, edx            ; put z2 in eax
  2617.         sub eax, esi            ; eax = dz = z2 - z1
  2618.         shl eax, 16             ; dz *= 65536, scale to 16.16 fixed point
  2619.         cdq                     ; set up for divide, sign extend eax into edx
  2620.         idiv ebx                ; get dzdx
  2621.  
  2622.         jmp zhlGoOn
  2623.  
  2624. zhlIHATESHORTJUMPS:
  2625.         jmp zhlDone
  2626.  
  2627.  
  2628. zhlGoOn:
  2629.         mov edx, eax            ; save dz/dx ratio in edx
  2630.         mov ebx, esi            ; eax = z1
  2631.         shl ebx, 16             ; ebx = z1 * 65536, scaled to 16.16 fixed point
  2632.  
  2633.         mov eax, cTop           ; get stored color (we killed ebp so we can't
  2634.                                 ; get any data off the stack)
  2635.  
  2636.         jcxz zhlMod             ; get out if nothing to draw
  2637.  
  2638.         ror edx, 16             ; set up ratio for adc (swap low, high words)
  2639.         ror ebx, 16             ; set up z1 for adc (swap low, high words)
  2640.  
  2641.         align 4                 ; I was once told this speeds things up...
  2642.  
  2643. zhlLoop:
  2644.  
  2645.         test BYTE PTR [edi], 0FFh       ; check to see if pixel is set
  2646.         jz zhlDontCheck                 ; if not, don't check z-buffer
  2647.  
  2648.         cmp [ebp], bx           ; check current z value against z-buffer
  2649.         jl zhlNoDisp            ; if z-buffer value is less, don't display
  2650.  
  2651. zhlDontCheck:
  2652.         mov [ebp], bx           ; write z value to z-buffer
  2653.         mov [edi], al           ; write color to screen
  2654.  
  2655. zhlNoDisp:
  2656.         add ebp, 2              ; next z-buffer address
  2657.         inc edi                 ; next screen address
  2658.         add ebx, edx            ; add z ratio to current z
  2659.         adc ebx, 0              ; add carry flag to complete 16.16 addition
  2660.  
  2661.         dec ecx                 ; pixels to draw - 1
  2662.         jnz zhlLoop             ; loop if any pixels are left to draw
  2663.  
  2664. zhlMod:
  2665.  
  2666. zhlDone:
  2667.         pop edi
  2668.         pop esi
  2669.         pop ebp
  2670.  
  2671.         ret 24                  ; we outta here...
  2672.  
  2673.  
  2674. zHline endp
  2675.  
  2676.  
  2677. ; zbuffer polygon draw
  2678.  
  2679. zp3Stack struc
  2680.                 dd  ?,?,?       ; room for regs
  2681.                 dd  ?           ; caller
  2682.         zp3c    dd  ?           ; color
  2683.         zp3z3   dd  ?           ; z3
  2684.         zp3y3   dd  ?           ; y3
  2685.         zp3x3   dd  ?           ; x3
  2686.         zp3z2   dd  ?           ; z2
  2687.         zp3y2   dd  ?           ; y2
  2688.         zp3x2   dd  ?           ; x2
  2689.         zp3z1   dd  ?           ; z1
  2690.         zp3y1   dd  ?           ; y1
  2691.         zp3x1   dd  ?           ; x1
  2692.  
  2693. zp3Stack ends
  2694.  
  2695.         public zpoly3
  2696.  
  2697. zpoly3 proc
  2698.  
  2699.         push ebp
  2700.         push edi
  2701.         push esi
  2702.  
  2703.         mov ebp, esp
  2704.  
  2705.         mov eax, [ebp].zp3y1
  2706.         mov ebx, [ebp].zp3y2
  2707.         mov ecx, [ebp].zp3y3
  2708.  
  2709.         ; sort the points based on y values
  2710.  
  2711. zyComp1:
  2712.         cmp eax, ebx
  2713.         jg zy2top
  2714.  
  2715.         mov yTop, eax                   ; sort the points, find top, middle,
  2716.         mov edx, [ebp].zp3x1            ; and bottom
  2717.         mov xTop, edx
  2718.         mov edx, [ebp].zp3z1
  2719.         mov zTop, edx
  2720.  
  2721.         mov yBot, ebx
  2722.         mov edx, [ebp].zp3x2
  2723.         mov xBot, edx
  2724.         mov edx, [ebp].zp3z2
  2725.         mov zBot, edx
  2726.  
  2727.         jmp zyComp2
  2728.  
  2729. zy2top: mov yTop, ebx
  2730.         mov edx, [ebp].zp3x2
  2731.         mov xTop, edx
  2732.         mov edx, [ebp].zp3z2
  2733.         mov zTop, edx
  2734.  
  2735.         mov yBot, eax
  2736.         mov edx, [ebp].zp3x1
  2737.         mov xBot, edx
  2738.         mov edx, [ebp].zp3z1
  2739.         mov zBot, edx
  2740.  
  2741. zyComp2:
  2742.         cmp ecx, yTop
  2743.         jg zyTopOK
  2744.  
  2745.         mov yTop, ecx
  2746.         mov edx, [ebp].zp3x3
  2747.         mov xTop, edx
  2748.         mov edx, [ebp].zp3z3
  2749.         mov zTop, edx
  2750.  
  2751.         cmp eax, ebx
  2752.         jg zy2mid
  2753.  
  2754.         mov yMid, eax
  2755.         mov edx, [ebp].zp3x1
  2756.         mov xMid, edx
  2757.         mov edx, [ebp].zp3z1
  2758.         mov zMid, edx
  2759.  
  2760.         mov yBot, ebx
  2761.         mov edx, [ebp].zp3x2
  2762.         mov xBot, edx
  2763.         mov edx, [ebp].zp3z2
  2764.         mov zBot, edx
  2765.  
  2766.  
  2767.         jmp zyCompDone
  2768.  
  2769. zy2mid: mov yMid, ebx
  2770.         mov edx, [ebp].zp3x2
  2771.         mov xMid, edx
  2772.         mov edx, [ebp].zp3z2
  2773.         mov zMid, edx
  2774.  
  2775.         mov yBot, eax
  2776.         mov edx, [ebp].zp3x1
  2777.         mov xBot, edx
  2778.         mov edx, [ebp].zp3z1
  2779.         mov zBot, edx
  2780.  
  2781.         jmp zyCompDone
  2782.  
  2783. zyTopOK:
  2784.         cmp ecx, yBot
  2785.         jg zybBad
  2786.  
  2787.         mov yMid, ecx
  2788.         mov edx, [ebp].zp3x3
  2789.         mov xMid, edx
  2790.         mov edx, [ebp].zp3z3
  2791.         mov zMid, edx
  2792.  
  2793.         jmp zyCompDone
  2794.  
  2795. zybBad: mov eax, yBot
  2796.         mov ebx, xBot
  2797.         mov edx, zBot
  2798.  
  2799.         mov yMid, eax
  2800.         mov xMid, ebx
  2801.         mov zMid, edx
  2802.  
  2803.         mov yBot, ecx
  2804.         mov edx, [ebp].zp3x3
  2805.         mov xBot, edx
  2806.         mov edx, [ebp].zp3z3
  2807.         mov zBot, edx
  2808.  
  2809.  
  2810. zyCompDone:
  2811.  
  2812.         mov eax, yTop           ; don't draw the polygon if its top is below
  2813.         mov ebx, yBot           ; the bottom of the screen, or if it's
  2814.         cmp eax, 199            ; bottom is above the top of the screen
  2815.         jg zfillDone
  2816.         cmp ebx, 0
  2817.         jl zfillDone
  2818.  
  2819.         ; now calculate the x values at each scanline for the longest side.
  2820.  
  2821.         mov eax, xBot
  2822.         mov ebx, xTop
  2823.         sub eax, ebx            ; calculate dx
  2824.         shl eax, 16
  2825.  
  2826.         mov ecx, yBot
  2827.         mov edx, yTop
  2828.         sub ecx, edx            ; calculate dy
  2829.  
  2830.         jecxz zedge1Horz        ; skip the div if dy = 0
  2831.  
  2832.         cdq                     ; sign extend eax into edx, set up for idiv
  2833.         idiv ecx                ; OOOH, SLOOW
  2834.  
  2835.         jmp zedge1Continue
  2836.  
  2837. zedge1Horz:
  2838.  
  2839.         jmp zedge2Start         ; forget the div if dy = 0
  2840.  
  2841. zedge1Continue:
  2842.  
  2843.         mov ecx, yBot
  2844.         mov ebx, yTop
  2845.         sub ecx, ebx            ; # of scanlines to trace
  2846.  
  2847.         shl ebx, 2              ; y1 * 4, offset into dword edgelist
  2848.         lea edi, lEdge          ; load edgelist
  2849.         add edi, ebx            ; add starting offset
  2850.  
  2851.         xor ebx, ebx
  2852.         mov edx, xTop           ; starting x value
  2853.         mov esi, yTop           ; starting y value
  2854.  
  2855.         ror eax, 16             ; set up dx/dy for 16.16 fixed point adc
  2856.  
  2857.         align 4
  2858.  
  2859. zedge1Loop:
  2860.  
  2861.         cmp esi, 0              ; crude form of clipping
  2862.         jl zskipThisLine1
  2863.  
  2864.         cmp esi, 199
  2865.         jg zedge2Start
  2866.  
  2867.         mov bx, dx              ; move integer part of x into bx
  2868.         mov [edi], ebx          ; store a dword in the edge list
  2869.  
  2870. zskipThisLine1:
  2871.  
  2872.         add edx, eax            ; add ratio to x
  2873.         adc edx, 0              ; carry flag completes addition
  2874.         add edi, 4              ; next scanline in edge list
  2875.         inc esi                 ; y++
  2876.         dec ecx                 ; scanlines to draw --
  2877.         jns zedge1Loop
  2878.  
  2879.         ; calculate x values for next side
  2880.  
  2881. zedge2Start:
  2882.  
  2883.         mov eax, xBot
  2884.         mov ebx, xMid
  2885.         sub eax, ebx
  2886.         shl eax, 16
  2887.  
  2888.         mov ecx, yBot
  2889.         mov edx, yMid
  2890.         sub ecx, edx
  2891.  
  2892.         jecxz zedge2Horz
  2893.  
  2894.         cdq
  2895.         idiv ecx
  2896.  
  2897.         jmp zedge2Continue
  2898.  
  2899. zedge2Horz:
  2900.  
  2901.         jmp zedge3Start
  2902.  
  2903. zedge2Continue:
  2904.  
  2905.         mov ecx, yBot
  2906.         mov ebx, yMid
  2907.         sub ecx, ebx
  2908.  
  2909.         shl ebx, 2
  2910.         lea edi, rEdge
  2911.         add edi, ebx
  2912.  
  2913.         xor ebx, ebx
  2914.         mov edx, xMid
  2915.         mov esi, yMid
  2916.  
  2917.         ror eax, 16
  2918.  
  2919.         align 4
  2920.  
  2921. zedge2Loop:
  2922.  
  2923.         cmp esi, 0
  2924.         jl zskipThisLine2
  2925.         cmp esi, 199
  2926.         jg zedge3Start
  2927.  
  2928.         mov bx, dx
  2929.         mov [edi], ebx
  2930.  
  2931. zskipThisLine2:
  2932.  
  2933.         add edx, eax
  2934.         adc edx, 0
  2935.         add edi, 4
  2936.         inc esi
  2937.         dec ecx
  2938.         jns zedge2Loop
  2939.  
  2940.         ; calculate x values for last side
  2941.  
  2942. zedge3Start:
  2943.  
  2944.         mov eax, xMid
  2945.         mov ebx, xTop
  2946.         sub eax, ebx
  2947.         shl eax, 16
  2948.  
  2949.         mov ecx, yMid
  2950.         mov edx, yTop
  2951.         sub ecx, edx
  2952.  
  2953.         jecxz zedge3Horz
  2954.  
  2955.         cdq
  2956.         idiv ecx
  2957.  
  2958.         jmp zedge3Continue
  2959.  
  2960. zedge3Horz:
  2961.  
  2962.         jmp zcolorStartc
  2963.  
  2964. zedge3Continue:
  2965.  
  2966.         mov ecx, yMid
  2967.         mov ebx, yTop
  2968.         sub ecx, ebx
  2969.  
  2970.         shl ebx, 2
  2971.         lea edi, rEdge
  2972.         add edi, ebx
  2973.  
  2974.         xor ebx, ebx
  2975.         mov edx, xTop
  2976.         mov esi, yTop
  2977.  
  2978.         ror eax, 16
  2979.  
  2980.         align 4
  2981.  
  2982. zedge3Loop:
  2983.  
  2984.         cmp esi, 0
  2985.         jl zskipThisLine3
  2986.  
  2987.         cmp esi, 199
  2988.         jg zcolorStartc
  2989.  
  2990.         mov bx, dx
  2991.         mov [edi], ebx
  2992.  
  2993. zskipThisLine3:
  2994.  
  2995.         add edx, eax
  2996.         adc edx, 0
  2997.         add edi, 4
  2998.         inc esi
  2999.         dec ecx
  3000.         jns zedge3Loop
  3001.  
  3002. zcolorStartc:
  3003.  
  3004.         ; now calculate the color values at each scanline for the longest side.
  3005.  
  3006.         mov eax, zBot
  3007.         mov ebx, zTop
  3008.         sub eax, ebx
  3009.         shl eax, 16
  3010.  
  3011.         mov ecx, yBot
  3012.         mov edx, yTop
  3013.         sub ecx, edx
  3014.  
  3015.         jecxz zedge1Horzc         ; skip the div if denominator = 0
  3016.  
  3017.         cdq
  3018.         idiv ecx
  3019.  
  3020.         jmp zedge1Continuec
  3021.  
  3022. zedge1Horzc:
  3023.  
  3024.         jmp zedge2Startc
  3025.  
  3026. zedge1Continuec:
  3027.  
  3028.         mov ecx, yBot
  3029.         mov ebx, yTop
  3030.         sub ecx, ebx
  3031.  
  3032.         shl ebx, 2
  3033.         lea edi, lZ
  3034.         add edi, ebx
  3035.  
  3036.         xor ebx, ebx
  3037.         mov edx, zTop
  3038.         mov esi, yTop
  3039.  
  3040.         ror eax, 16
  3041.  
  3042.         align 4
  3043.  
  3044. zedge1Loopc:
  3045.  
  3046.         cmp esi, 0
  3047.         jl zskipThisLine1c
  3048.  
  3049.         cmp esi, 199
  3050.         jg zedge2Startc
  3051.  
  3052.         mov bx, dx
  3053.         mov [edi], ebx
  3054.  
  3055. zskipThisLine1c:
  3056.  
  3057.         add edx, eax
  3058.         adc edx, 0
  3059.         add edi, 4
  3060.         inc esi
  3061.         dec ecx
  3062.         jns zedge1Loopc
  3063.  
  3064. zedge2Startc:
  3065.  
  3066.         mov eax, zBot
  3067.         mov ebx, zMid
  3068.         sub eax, ebx
  3069.         shl eax, 16
  3070.  
  3071.         mov ecx, yBot
  3072.         mov edx, yMid
  3073.         sub ecx, edx
  3074.  
  3075.         jecxz zedge2Horzc
  3076.  
  3077.         cdq
  3078.         idiv ecx
  3079.  
  3080.         jmp zedge2Continuec
  3081.  
  3082. zedge2Horzc:
  3083.  
  3084.         jmp zedge3Startc
  3085.  
  3086. zedge2Continuec:
  3087.  
  3088.         mov ecx, yBot
  3089.         mov ebx, yMid
  3090.         sub ecx, ebx
  3091.  
  3092.         shl ebx, 2
  3093.         lea edi, rZ
  3094.         add edi, ebx
  3095.  
  3096.         xor ebx, ebx
  3097.         mov edx, zMid
  3098.         mov esi, yMid
  3099.  
  3100.         ror eax, 16
  3101.  
  3102.         align 4
  3103.  
  3104. zedge2Loopc:
  3105.  
  3106.         cmp esi, 0
  3107.         jl zskipThisLine2c
  3108.  
  3109.         cmp esi, 199
  3110.         jg zedge3Startc
  3111.  
  3112.         mov bx, dx
  3113.         mov [edi], ebx
  3114.  
  3115. zskipThisLine2c:
  3116.  
  3117.         add edx, eax
  3118.         adc edx, 0
  3119.         add edi, 4
  3120.         inc esi
  3121.         dec ecx
  3122.         jns zedge2Loopc
  3123.  
  3124.         ; calculate z values for the last side
  3125.  
  3126. zedge3Startc:
  3127.  
  3128.         mov eax, zMid
  3129.         mov ebx, zTop
  3130.         sub eax, ebx
  3131.         shl eax, 16
  3132.  
  3133.         mov ecx, yMid
  3134.         mov edx, yTop
  3135.         sub ecx, edx
  3136.  
  3137.         jecxz zedge3Horzc
  3138.  
  3139.         cdq
  3140.         idiv ecx
  3141.  
  3142.         jmp zedge3Continuec
  3143.  
  3144. zedge3Horzc:
  3145.  
  3146.         jmp zfillStart
  3147.  
  3148. zedge3Continuec:
  3149.  
  3150.         mov ecx, yMid
  3151.         mov ebx, yTop
  3152.         sub ecx, ebx
  3153.  
  3154.         shl ebx, 2
  3155.         lea edi, rZ
  3156.         add edi, ebx
  3157.  
  3158.         xor ebx, ebx
  3159.         mov edx, zTop
  3160.         mov esi, yTop
  3161.  
  3162.         ror eax, 16
  3163.  
  3164.         align 4
  3165.  
  3166. zedge3Loopc:
  3167.  
  3168.         cmp esi, 0
  3169.         jl zskipThisLine3c
  3170.  
  3171.         cmp esi, 199
  3172.         jg zfillStart
  3173.  
  3174.         mov bx, dx
  3175.         mov [edi], ebx
  3176.  
  3177. zskipThisLine3c:
  3178.  
  3179.         add edx, eax
  3180.         adc edx, 0
  3181.         add edi, 4
  3182.         inc esi
  3183.         dec ecx
  3184.         jns zedge3Loopc
  3185.  
  3186.         ; time to fill...
  3187.  
  3188. zfillStart:
  3189.  
  3190.         mov eax, yTop
  3191.         mov ebx, yBot
  3192.  
  3193.         cmp eax, 0
  3194.         jge zcheckBot
  3195.         xor eax, eax
  3196.         mov yTop, eax
  3197.  
  3198. zcheckBot:
  3199.  
  3200.         cmp ebx, 199
  3201.         jle zfillNOW
  3202.         mov ebx, 199
  3203.         mov yBot, ebx
  3204.  
  3205. zfillNOW:
  3206.  
  3207.         lea esi, lEdge
  3208.         lea edi, rEdge
  3209.  
  3210.         lea eax, lZ
  3211.         lea edx, rZ
  3212.  
  3213.         mov ecx, yTop
  3214.         shl ecx, 2
  3215.  
  3216.         add esi, ecx
  3217.         add edi, ecx
  3218.         add eax, ecx
  3219.         add edx, ecx
  3220.  
  3221.         shr ecx, 2
  3222.  
  3223.         align 4
  3224.  
  3225. zfillME: push ecx
  3226.  
  3227. zx1OKToo:
  3228.         push esi        ; save important registers
  3229.         push eax
  3230.         push edi
  3231.         push edx
  3232.  
  3233.         push [esi]      ; push arguments on stack
  3234.         push [eax]
  3235.         push [edi]
  3236.         push [edx]
  3237.         push ecx
  3238.         push [ebp].zp3c
  3239.  
  3240.         call zHline     ; draw a horizontal line
  3241.  
  3242.         pop edx         ; restore important schtuff
  3243.         pop edi
  3244.         pop eax
  3245.         pop esi
  3246.  
  3247. znextLine:
  3248.         pop ecx
  3249.  
  3250.         add esi, 4      ; go to next element in all lists
  3251.         add edi, 4
  3252.         add eax, 4
  3253.         add edx, 4
  3254.  
  3255.         inc ecx         ; y++
  3256.         cmp ecx, yBot   ; see if we're done yet
  3257.         jle zfillME     ; back to work!        
  3258.  
  3259. zfillDone:
  3260.  
  3261.         pop esi         
  3262.         pop edi
  3263.         pop ebp
  3264.  
  3265.         ret 40          ; see ya...
  3266.  
  3267. zpoly3 endp
  3268.  
  3269.  
  3270. ; zbuffer gouraud hline draw
  3271.  
  3272. gzhlStack struc
  3273.  
  3274.                  dd ?,?,?        ; ebp esi edi
  3275.                  dd ?            ; caller
  3276.         gzhly    dd ?            ; y
  3277.         gzhlc2   dd ?            ; c2
  3278.         gzhlz2   dd ?            ; z2
  3279.         gzhlx2   dd ?            ; x2
  3280.         gzhlc1   dd ?            ; c1
  3281.         gzhlz1   dd ?            ; z1
  3282.         gzhlx1   dd ?            ; x1
  3283.  
  3284. gzhlStack ends
  3285.  
  3286.  
  3287. ; gzHline draws a gouraud shaded z-buffered horizontal line between <x1,z1,c1>
  3288. ; and <x2,z2,c2>.  This code is very similar to the zHline routine, with the
  3289. ; exception that I interpolate color values as well as z values.
  3290.  
  3291.  
  3292.         public gzHline
  3293.  
  3294. gzHline proc     ; zbuffered hline routine
  3295.  
  3296.         push ebp
  3297.         push esi
  3298.         push edi
  3299.         mov ebp, esp
  3300.  
  3301.         mov eax, [ebp].gzhlc1   ; save the color values cause we're gonna
  3302.         mov cBot, eax           ; trash ebp later on
  3303.         mov eax, [ebp].gzhlc2
  3304.         mov cTop, eax
  3305.  
  3306.         mov eax, [ebp].gzhly    ; y value
  3307.  
  3308.         lea eax, [eax + eax*4]  ; eax = eax * 320
  3309.         shl eax, 6
  3310.  
  3311.         push eax                ; save the offset for later
  3312.  
  3313.         mov edi, curPage        ; get current video page
  3314.  
  3315.         mov ecx, [ebp].gzhlx1   ; get x's and z's
  3316.         mov ebx, [ebp].gzhlx2
  3317.         mov esi, [ebp].gzhlz1
  3318.         mov edx, [ebp].gzhlz2
  3319.  
  3320.         movsx ecx, cx           ; sign extend 16 bit values into 32 bit regs
  3321.         movsx ebx, bx
  3322.         movsx esi, si
  3323.         movsx edx, dx
  3324.  
  3325.         cmp ebx, ecx            ; make sure x2 > x1
  3326.         jg gzhlDraw             ; if so, keep going
  3327.         xchg ebx, ecx           ; if not, switch everything
  3328.         xchg esi, edx
  3329.         mov eax, cTop
  3330.         mov temp, eax
  3331.         mov eax, cBot
  3332.         mov cTop, eax
  3333.         mov eax, temp
  3334.         mov cBot, eax
  3335.  
  3336. gzhlDraw:
  3337.         mov [ebp].gzhlz2, edx   ; free a register by saving it on the stack
  3338.  
  3339.         cmp ecx, 0              ; clip the left edge
  3340.         jg gzhlx1ok
  3341.         mov ecx, 0
  3342.  
  3343. gzhlx1ok:
  3344.         cmp ecx, 320            ; quit if left edge is off the right side of
  3345.         jl gzhlx1small          ; the screen
  3346.         pop eax
  3347.         jmp gzhlDone
  3348.  
  3349. gzhlx1small:
  3350.  
  3351.         cmp ebx, 319            ; clip the right edge
  3352.         jl gzhlx2ok
  3353.         mov ebx, 319
  3354.  
  3355. gzhlx2ok:
  3356.         cmp ebx, 0              ; quit if right edge is off the left side of
  3357.         jg gzhlx2big            ; the screen
  3358.         pop eax
  3359.         jmp gzhlDone
  3360.  
  3361. gzhlx2big:
  3362.  
  3363.         mov ebp, zBuf   ; get the z-buffer
  3364.  
  3365.         pop eax         ; get the saved offset
  3366.  
  3367.         add eax, ecx    ; starting offset + x1
  3368.         add edi, eax    ; starting offset into screen
  3369.         shl eax, 1      ; * 2 for words
  3370.         add ebp, eax    ; starting offset into z-buffer
  3371.         shr eax, 1      ; back to bytes
  3372.  
  3373.         sub ebx, ecx    ; get # of pix to draw
  3374.         mov ecx, ebx
  3375.  
  3376.         jecxz gzhlIHATESHORTJUMPS
  3377.  
  3378.         mov eax, edx    ; get z1
  3379.         sub eax, esi    ; z2 - z1
  3380.         shl eax, 16     ; dz *= 65536, convert to 16.16 fixed point
  3381.  
  3382.         cdq             ; sign extend eax into edx for divide
  3383.         idiv ebx        ; get dz/dx
  3384.  
  3385.         mov temp, eax   ; save ratio (dz/dx)
  3386.  
  3387.         ; comment out this block if you want to use a constant dc/dx for the
  3388.         ; entire polygon.  This eliminates one idiv per scanline, but there
  3389.         ; is a noticable decrease in quality.  In my opinion, the added
  3390.         ; quality given by the idiv is worth a slight slowdown
  3391.  
  3392.         mov edx, cBot   ; get c1
  3393.         mov eax, cTop   ; get c2
  3394.         sub eax, edx    ; c2 - c1
  3395.         shl eax, 8      ; dc *= 256
  3396.  
  3397.         cdq             ; sign extend before divide
  3398.         idiv ebx        ; eax = dc/dx
  3399.  
  3400.         ; uncomment the next line to get the constant ratio for the plane
  3401.  
  3402.         ;mov eax, cRatio
  3403.  
  3404.         jmp gzhlGoOn
  3405.  
  3406. gzhlIHATESHORTJUMPS:
  3407.         jmp gzhlDone
  3408.  
  3409.  
  3410. gzhlGoOn:
  3411.         mov edx, temp   ; edx = dzdx * 65536
  3412.         mov ebx, esi    ; ebx = z1
  3413.         shl ebx, 16     ; ebx *= 65536
  3414.  
  3415.         mov esi, eax    ; esi = dcdx * 256
  3416.         mov eax, cBot   ; eax = c1
  3417.         shl eax, 8      ; c1 *= 256
  3418.  
  3419.         cmp ecx, 0
  3420.         jz gzhlDone     ; get out if nothing to draw
  3421.  
  3422.         rol ebx, 16     ; convert z1 to be used with 16.16 adc
  3423.         rol edx, 16     ; convert dz/dx to be used with 16.16 adc
  3424.  
  3425.         ; eax = c1 << 8
  3426.         ; ebx = z1 << 16
  3427.         ; ecx = count
  3428.         ; edx = dz/dx << 16
  3429.         ; esi = dc/dx << 8
  3430.         ; edi = [screen]
  3431.         ; ebp = [zbuf]
  3432.  
  3433.         align 4
  3434.  
  3435. gzhlByteLoop:
  3436.  
  3437.         ; HEY MainFrame!  Uncomment the next two lines to do z-clipping.  The
  3438.         ; problem with z-clipping is that I use words in the z-buffer, so I
  3439.         ; clip at 0, 64k, 128k, etc.  IT IS TOTALLY WORTHLESS :)
  3440.  
  3441.         ;cmp bx, 0                 ; don't draw anything behind the eye
  3442.         ;jl gzhlNoDisp
  3443.  
  3444.         test BYTE PTR [edi], 0FFh ; check to see if the pixel is set
  3445.         jz gzhlDontCheck          ; if not, don't bother checking the zbuffer
  3446.  
  3447.         cmp [ebp], bx             ; check z-buffer value
  3448.         jl gzhlNoDisp
  3449.  
  3450. gzhlDontCheck:
  3451.         mov [ebp], bx             ; write to the z-buffer
  3452.         mov [edi], ah             ; write to the screen
  3453.  
  3454. gzhlNoDisp:
  3455.         add ebp, 2              ; next z-buffer address
  3456.         inc edi                 ; next screen address
  3457.         add ebx, edx            ; z + dz
  3458.         adc ebx, 0              ; add carry flag to complete 16.16 addition
  3459.         add eax, esi            ; c + dc
  3460.  
  3461.         dec ecx                 ; pixToDraw - 1
  3462.         jnz gzhlByteLoop        ; draw som mo'
  3463.  
  3464. gzhlMod:
  3465.  
  3466. gzhlDone:
  3467.         pop edi
  3468.         pop esi
  3469.         pop ebp
  3470.  
  3471.         ret 28
  3472.  
  3473.  
  3474. gzhline endp
  3475.  
  3476.  
  3477. ; This routine draws a gouraud shaded z-buffered fully clipped polygon,
  3478. ; sales tax and 25% royalty to the author not included.  It is VERY similar
  3479. ; to the zpoly3 routine, with the exception that z is traced along with c
  3480. ; and x.  Because of the similarities, I am not going to comment this
  3481. ; routine as thouroughly as I did zpoly3
  3482.  
  3483.  
  3484. ; zbuffer gouraud polygon draw
  3485.  
  3486. gzp3Stack struc
  3487.                  dd  ?,?,?       ; room for regs
  3488.                  dd  ?           ; caller
  3489.         gzp3c3   dd  ?           ; c3
  3490.         gzp3z3   dd  ?           ; z3
  3491.         gzp3y3   dd  ?           ; y3
  3492.         gzp3x3   dd  ?           ; x3
  3493.         gzp3c2   dd  ?           ; c2
  3494.         gzp3z2   dd  ?           ; z2
  3495.         gzp3y2   dd  ?           ; y2
  3496.         gzp3x2   dd  ?           ; x2
  3497.         gzp3c1   dd  ?           ; c1
  3498.         gzp3z1   dd  ?           ; z1
  3499.         gzp3y1   dd  ?           ; y1
  3500.         gzp3x1   dd  ?           ; x1
  3501.  
  3502. gzp3Stack ends
  3503.  
  3504.         public gzpoly3
  3505.  
  3506. gzpoly3 proc
  3507.  
  3508.         push ebp
  3509.         push edi
  3510.         push esi
  3511.  
  3512.         mov ebp, esp
  3513.  
  3514.         mov eax, [ebp].gzp3y1
  3515.         mov ebx, [ebp].gzp3y2
  3516.         mov ecx, [ebp].gzp3y3
  3517.  
  3518.         ; sort the points based on y values
  3519.  
  3520. gzyComp1:
  3521.         cmp eax, ebx
  3522.         jg gzy2top
  3523.  
  3524.         mov yTop, eax           ; do the ol' sorting thing, find top, middle,        
  3525.         mov edx, [ebp].gzp3x1   ; and bottom vertices                                               
  3526.         mov xTop, edx
  3527.         mov edx, [ebp].gzp3z1
  3528.         mov zTop, edx
  3529.         mov edx, [ebp].gzp3c1
  3530.         mov cTop, edx
  3531.  
  3532.         mov yBot, ebx
  3533.         mov edx, [ebp].gzp3x2
  3534.         mov xBot, edx
  3535.         mov edx, [ebp].gzp3z2
  3536.         mov zBot, edx
  3537.         mov edx, [ebp].gzp3c2
  3538.         mov cBot, edx
  3539.  
  3540.         jmp gzyComp2
  3541.  
  3542. gzy2top:
  3543.         mov yTop, ebx
  3544.         mov edx, [ebp].gzp3x2
  3545.         mov xTop, edx
  3546.         mov edx, [ebp].gzp3z2
  3547.         mov zTop, edx
  3548.         mov edx, [ebp].gzp3c2
  3549.         mov cTop, edx
  3550.  
  3551.         mov yBot, eax
  3552.         mov edx, [ebp].gzp3x1
  3553.         mov xBot, edx
  3554.         mov edx, [ebp].gzp3z1
  3555.         mov zBot, edx
  3556.         mov edx, [ebp].gzp3c1
  3557.         mov cBot, edx
  3558.  
  3559. gzyComp2:
  3560.         cmp ecx, yTop
  3561.         jg gzyTopOK
  3562.  
  3563.         mov yTop, ecx
  3564.         mov edx, [ebp].gzp3x3
  3565.         mov xTop, edx
  3566.         mov edx, [ebp].gzp3z3
  3567.         mov zTop, edx
  3568.         mov edx, [ebp].gzp3c3
  3569.         mov cTop, edx
  3570.  
  3571.         cmp eax, ebx
  3572.         jg gzy2mid
  3573.  
  3574.         mov yMid, eax
  3575.         mov edx, [ebp].gzp3x1
  3576.         mov xMid, edx
  3577.         mov edx, [ebp].gzp3z1
  3578.         mov zMid, edx
  3579.         mov edx, [ebp].gzp3c1
  3580.         mov cMid, edx
  3581.  
  3582.         mov yBot, ebx
  3583.         mov edx, [ebp].gzp3x2
  3584.         mov xBot, edx
  3585.         mov edx, [ebp].gzp3z2
  3586.         mov zBot, edx
  3587.         mov edx, [ebp].gzp3c2
  3588.         mov cBot, edx
  3589.  
  3590.  
  3591.         jmp gzyCompDone
  3592.  
  3593. gzy2mid:
  3594.         mov yMid, ebx
  3595.         mov edx, [ebp].gzp3x2
  3596.         mov xMid, edx
  3597.         mov edx, [ebp].gzp3z2
  3598.         mov zMid, edx
  3599.         mov edx, [ebp].gzp3c2
  3600.         mov cMid, edx
  3601.  
  3602.         mov yBot, eax
  3603.         mov edx, [ebp].gzp3x1
  3604.         mov xBot, edx
  3605.         mov edx, [ebp].gzp3z1
  3606.         mov zBot, edx
  3607.         mov edx, [ebp].gzp3c1
  3608.         mov cBot, edx
  3609.  
  3610.         jmp gzyCompDone
  3611.  
  3612. gzyTopOK:
  3613.         cmp ecx, yBot
  3614.         jg gzybBad
  3615.  
  3616.         mov yMid, ecx
  3617.         mov edx, [ebp].gzp3x3
  3618.         mov xMid, edx
  3619.         mov edx, [ebp].gzp3z3
  3620.         mov zMid, edx
  3621.         mov edx, [ebp].gzp3c3
  3622.         mov cMid, edx
  3623.  
  3624.         jmp gzyCompDone
  3625.  
  3626. gzybBad:
  3627.         mov eax, yBot
  3628.         mov ebx, xBot
  3629.         mov edx, zBot
  3630.         mov esi, cBot
  3631.  
  3632.         mov yMid, eax
  3633.         mov xMid, ebx
  3634.         mov zMid, edx
  3635.         mov cMid, esi
  3636.  
  3637.         mov yBot, ecx
  3638.         mov edx, [ebp].gzp3x3
  3639.         mov xBot, edx
  3640.         mov edx, [ebp].gzp3z3
  3641.         mov zBot, edx
  3642.         mov edx, [ebp].gzp3c3
  3643.         mov cBot, edx
  3644.  
  3645.  
  3646. gzyCompDone:
  3647.  
  3648.         mov eax, yTop           ; get y1        
  3649.         mov ebx, yBot           ; get y2
  3650.         cmp eax, 199            ; get out if top is below the screen bottom
  3651.         jg gzfillDone
  3652.         cmp ebx, 0              ; get out if bottom is above screen top
  3653.         jl gzfillDone
  3654.  
  3655.         ; now calculate the x values at each scanline for the longest side.
  3656.  
  3657.         mov eax, xBot          
  3658.         mov ebx, xTop
  3659.         sub eax, ebx            ; calculate dx
  3660.         shl eax, 16
  3661.  
  3662.         mov ecx, yBot
  3663.         mov edx, yTop
  3664.         sub ecx, edx            ; calculate dy
  3665.  
  3666.         jecxz gzedge1Horz       ; skip the div if dy = 0
  3667.  
  3668.         cdq
  3669.         idiv ecx                ; calcualte dx/dy
  3670.  
  3671.         jmp gzedge1Continue
  3672.  
  3673. gzedge1Horz:
  3674.  
  3675.         jmp gzedge2Start
  3676.  
  3677. gzedge1Continue:
  3678.         mov ecx, yBot
  3679.         mov ebx, yTop
  3680.         sub ecx, ebx            ; # of scanlines to trace
  3681.  
  3682.         shl ebx, 2              ; starting offset into edgelist                                
  3683.         lea edi, lEdge          ; load edgelist
  3684.         add edi, ebx            ; go to start of this side
  3685.  
  3686.         xor ebx, ebx
  3687.         mov edx, xTop           ; x1
  3688.         mov esi, yTop           ; y1
  3689.  
  3690.         ror eax, 16             ; set up for 16.16 fixed point adc
  3691.  
  3692.         align 4
  3693.  
  3694. gzedge1Loop:
  3695.  
  3696.         cmp esi, 0
  3697.         jl gzskipThisLine1      ; clip the top of this edge
  3698.  
  3699.         cmp esi, 199            ; clip the bottom of this edge
  3700.         jg gzedge2Start
  3701.  
  3702.         mov bx, dx              ; move integer part of edx into bx
  3703.         mov [edi], ebx          ; store ebx in edgelist
  3704.  
  3705. gzskipThisLine1:
  3706.  
  3707.         add edx, eax            ; add ratio to x
  3708.         adc edx, 0              ; carry flag completes 16.16 addition
  3709.         add edi, 4              ; next element in edgelist
  3710.         inc esi                 ; next scanline
  3711.         dec ecx                 ; linesToDo --
  3712.         jns gzedge1Loop         ; do som mo'!
  3713.  
  3714.         ; calculate x values for next side
  3715.  
  3716. gzedge2Start:                   ; the scan conversion process outlined above
  3717.                                 ; is repeated for all edges, scanning x,
  3718.         mov eax, xBot           ; color, and z values.  IT IS ALL DONE
  3719.         mov ebx, xMid           ; EXACTLY AS IT IS DONE ABOVE
  3720.         sub eax, ebx
  3721.         shl eax, 16
  3722.  
  3723.         mov ecx, yBot
  3724.         mov edx, yMid
  3725.         sub ecx, edx
  3726.  
  3727.         jecxz gzedge2Horz
  3728.  
  3729.         cdq
  3730.         idiv ecx
  3731.  
  3732.         jmp gzedge2Continue
  3733.  
  3734. gzedge2Horz:
  3735.  
  3736.         jmp gzedge3Start
  3737.  
  3738. gzedge2Continue:
  3739.         mov ecx, yBot
  3740.         mov ebx, yMid
  3741.         sub ecx, ebx
  3742.  
  3743.         shl ebx, 2
  3744.         lea edi, rEdge
  3745.         add edi, ebx
  3746.  
  3747.         xor ebx, ebx
  3748.         mov edx, xMid
  3749.         mov esi, yMid
  3750.  
  3751.         ror eax, 16
  3752.  
  3753.         align 4
  3754.  
  3755. gzedge2Loop:
  3756.  
  3757.         cmp esi, 0
  3758.         jl gzskipThisLine2
  3759.  
  3760.         cmp esi, 199
  3761.         jg gzedge3Start
  3762.  
  3763.         mov bx, dx
  3764.         mov [edi], ebx
  3765.  
  3766. gzskipThisLine2:
  3767.  
  3768.         add edx, eax
  3769.         adc edx, 0
  3770.         add edi, 4
  3771.         inc esi
  3772.         dec ecx
  3773.         jns gzedge2Loop
  3774.  
  3775.         ; calculate x values for last side
  3776.  
  3777. gzedge3Start:
  3778.  
  3779.         mov eax, xMid
  3780.         mov ebx, xTop
  3781.         sub eax, ebx
  3782.         shl eax, 16
  3783.  
  3784.         mov ecx, yMid
  3785.         mov edx, yTop
  3786.         sub ecx, edx
  3787.  
  3788.         jecxz gzedge3Horz
  3789.  
  3790.         cdq
  3791.         idiv ecx
  3792.  
  3793.         jmp gzedge3Continue
  3794.  
  3795. gzedge3Horz:
  3796.  
  3797.         jmp gzcolorStartc
  3798.  
  3799. gzedge3Continue:
  3800.  
  3801.         mov ecx, yMid
  3802.         mov ebx, yTop
  3803.         sub ecx, ebx
  3804.  
  3805.         shl ebx, 2
  3806.         lea edi, rEdge
  3807.         add edi, ebx
  3808.  
  3809.         xor ebx, ebx
  3810.         mov edx, xTop
  3811.         mov esi, yTop
  3812.  
  3813.         ror eax, 16
  3814.  
  3815.         align 4
  3816.  
  3817. gzedge3Loop:
  3818.  
  3819.         cmp esi, 0
  3820.         jl gzskipThisLine3
  3821.         cmp esi, 199
  3822.         jg gzcolorStartc
  3823.  
  3824.         mov bx, dx
  3825.         mov [edi], ebx
  3826.  
  3827. gzskipThisLine3:
  3828.  
  3829.         add edx, eax
  3830.         adc edx, 0
  3831.         add edi, 4
  3832.         inc esi
  3833.         dec ecx
  3834.         jns gzedge3Loop
  3835.  
  3836. gzcolorStartc:
  3837.  
  3838.         ; now calculate the z values at each scanline for the longest side.
  3839.  
  3840.         mov eax, zBot
  3841.         mov ebx, zTop
  3842.         sub eax, ebx
  3843.         shl eax, 16
  3844.  
  3845.         mov ecx, yBot
  3846.         mov edx, yTop
  3847.         sub ecx, edx
  3848.  
  3849.         jecxz gzedge1Horzc         ; skip the div if denominator = 0
  3850.  
  3851.         cdq
  3852.         idiv ecx
  3853.  
  3854.         jmp gzedge1Continuec
  3855.  
  3856. gzedge1Horzc:
  3857.  
  3858.         jmp gzedge2Startc
  3859.  
  3860. gzedge1Continuec:
  3861.  
  3862.         mov ecx, yBot
  3863.         mov ebx, yTop
  3864.         sub ecx, ebx
  3865.  
  3866.         shl ebx, 2
  3867.  
  3868.         lea edi, lZ
  3869.         add edi, ebx
  3870.  
  3871.         xor ebx, ebx
  3872.         mov edx, zTop
  3873.         mov esi, yTop
  3874.  
  3875.         ror eax, 16
  3876.  
  3877.         align 4
  3878.  
  3879. gzedge1Loopc:
  3880.  
  3881.         cmp esi, 0
  3882.         jl gzskipThisLine1c
  3883.  
  3884.         cmp esi, 199
  3885.         jg gzedge2Startc
  3886.  
  3887.         mov bx, dx
  3888.         mov [edi], ebx
  3889.  
  3890. gzskipThisLine1c:
  3891.  
  3892.         add edx, eax
  3893.         adc edx, 0
  3894.         add edi, 4
  3895.         inc esi
  3896.         dec ecx
  3897.         jns gzedge1Loopc
  3898.  
  3899.         ; calculate x values for next side
  3900.  
  3901. gzedge2Startc:
  3902.  
  3903.         mov eax, zBot
  3904.         mov ebx, zMid
  3905.         sub eax, ebx
  3906.         shl eax, 16
  3907.  
  3908.         mov ecx, yBot
  3909.         mov edx, yMid
  3910.         sub ecx, edx
  3911.  
  3912.         jecxz gzedge2Horzc
  3913.  
  3914.         cdq
  3915.         idiv ecx
  3916.  
  3917.         jmp gzedge2Continuec
  3918.  
  3919. gzedge2Horzc:
  3920.  
  3921.         jmp gzedge3Startc
  3922.  
  3923. gzedge2Continuec:
  3924.  
  3925.         mov ecx, yBot
  3926.         mov ebx, yMid
  3927.         sub ecx, ebx
  3928.  
  3929.         shl ebx, 2
  3930.         lea edi, rZ
  3931.         add edi, ebx
  3932.  
  3933.         xor ebx, ebx
  3934.         mov edx, zMid
  3935.         mov esi, yMid
  3936.  
  3937.         ror eax, 16
  3938.  
  3939.         align 4
  3940.  
  3941. gzedge2Loopc:
  3942.  
  3943.         cmp esi, 0
  3944.         jl gzskipThisLine2c
  3945.  
  3946.         cmp esi, 199
  3947.         jg gzedge3Startc
  3948.  
  3949.         mov bx, dx
  3950.         mov [edi], ebx
  3951.  
  3952. gzskipThisLine2c:
  3953.  
  3954.         add edx, eax
  3955.         adc edx, 0
  3956.         add edi, 4
  3957.         inc esi
  3958.         dec ecx
  3959.         jns gzedge2Loopc
  3960.  
  3961.         ; calculate x values for last side
  3962.  
  3963. gzedge3Startc:
  3964.  
  3965.         mov eax, zMid
  3966.         mov ebx, zTop
  3967.         sub eax, ebx
  3968.         shl eax, 16
  3969.  
  3970.         mov ecx, yMid
  3971.         mov edx, yTop
  3972.         sub ecx, edx
  3973.  
  3974.         jecxz gzedge3Horzc
  3975.  
  3976.         cdq
  3977.         idiv ecx
  3978.  
  3979.         jmp gzedge3Continuec
  3980.  
  3981. gzedge3Horzc:
  3982.  
  3983.         jmp gcolorStartcz
  3984.  
  3985. gzedge3Continuec:
  3986.  
  3987.         mov ecx, yMid
  3988.         mov ebx, yTop
  3989.         sub ecx, ebx
  3990.  
  3991.         shl ebx, 2
  3992.         lea edi, rZ
  3993.         add edi, ebx
  3994.  
  3995.         xor ebx, ebx
  3996.         mov edx, zTop
  3997.         mov esi, yTop
  3998.  
  3999.         ror eax, 16
  4000.  
  4001.         align 4
  4002.  
  4003. gzedge3Loopc:
  4004.  
  4005.         cmp esi, 0
  4006.         jl gzskipThisLine3c
  4007.  
  4008.         cmp esi, 199
  4009.         jg gcolorStartcz
  4010.  
  4011.         mov bx, dx
  4012.         mov [edi], ebx
  4013.  
  4014. gzskipThisLine3c:
  4015.  
  4016.         add edx, eax
  4017.         adc edx, 0
  4018.         add edi, 4
  4019.         inc esi
  4020.         dec ecx
  4021.         jns gzedge3Loopc
  4022.  
  4023. gcolorStartcz:
  4024.  
  4025.         ; now calculate the color values at each scanline for the longest side.
  4026.  
  4027.         mov eax, cBot
  4028.         mov ebx, cTop
  4029.         sub eax, ebx
  4030.         shl eax, 16
  4031.  
  4032.         mov ecx, yBot
  4033.         mov edx, yTop
  4034.         sub ecx, edx
  4035.  
  4036.         jecxz gedge1Horzcz         ; skip the div if denominator = 0
  4037.  
  4038.         cdq
  4039.         idiv ecx
  4040.  
  4041.         jmp gedge1Continuecz
  4042.  
  4043. gedge1Horzcz:
  4044.  
  4045.         jmp gedge2Startcz
  4046.  
  4047. gedge1Continuecz:
  4048.  
  4049.         mov ecx, yBot
  4050.         mov ebx, yTop
  4051.         sub ecx, ebx
  4052.  
  4053.         shl ebx, 2
  4054.         lea edi, lColor
  4055.         add edi, ebx
  4056.  
  4057.         xor ebx, ebx
  4058.         mov edx, cTop
  4059.         mov esi, yTop
  4060.  
  4061.         ror eax, 16
  4062.  
  4063.         align 4
  4064.  
  4065. gedge1Loopcz:
  4066.  
  4067.         cmp esi, 0
  4068.         jl gskipThisLine1cz
  4069.  
  4070.         cmp esi, 199
  4071.         jg gedge2Startcz
  4072.  
  4073.         mov bx, dx
  4074.         mov [edi], ebx
  4075.  
  4076. gskipThisLine1cz:
  4077.  
  4078.         add edx, eax
  4079.         adc edx, 0
  4080.         add edi, 4
  4081.         inc esi
  4082.         dec ecx
  4083.         jns gedge1Loopcz
  4084.  
  4085.         ; calculate x values for next side
  4086.  
  4087. gedge2Startcz:
  4088.  
  4089.         mov eax, cBot
  4090.         mov ebx, cMid
  4091.         sub eax, ebx
  4092.         shl eax, 16
  4093.  
  4094.         mov ecx, yBot
  4095.         mov edx, yMid
  4096.         sub ecx, edx
  4097.  
  4098.         jecxz gedge2Horzcz
  4099.  
  4100.         cdq
  4101.         idiv ecx
  4102.  
  4103.         jmp gedge2Continuecz
  4104.  
  4105. gedge2Horzcz:
  4106.  
  4107.         jmp gedge3Startcz
  4108.  
  4109. gedge2Continuecz:
  4110.  
  4111.         mov ecx, yBot
  4112.         mov ebx, yMid
  4113.         sub ecx, ebx
  4114.  
  4115.         shl ebx, 2
  4116.         lea edi, rColor
  4117.         add edi, ebx
  4118.  
  4119.         xor ebx, ebx
  4120.         mov edx, cMid
  4121.         mov esi, yMid
  4122.  
  4123.         ror eax, 16
  4124.  
  4125.         align 4
  4126.  
  4127. gedge2Loopcz:
  4128.  
  4129.         cmp esi, 0
  4130.         jl gskipThisLine2cz
  4131.  
  4132.         cmp esi, 199
  4133.         jg gedge3Startcz
  4134.  
  4135.         mov bx, dx
  4136.         mov [edi], ebx
  4137.  
  4138. gskipThisLine2cz:
  4139.  
  4140.         add edx, eax
  4141.         adc edx, 0
  4142.         add edi, 4
  4143.         inc esi
  4144.         dec ecx
  4145.         jns gedge2Loopcz
  4146.  
  4147.         ; calculate x values for last side
  4148.  
  4149. gedge3Startcz:
  4150.  
  4151.         mov eax, cMid
  4152.         mov ebx, cTop
  4153.         sub eax, ebx
  4154.         shl eax, 16
  4155.  
  4156.         mov ecx, yMid
  4157.         mov edx, yTop
  4158.         sub ecx, edx
  4159.  
  4160.         jecxz gedge3Horzcz
  4161.  
  4162.         cdq
  4163.         idiv ecx
  4164.  
  4165.         jmp gedge3Continuecz
  4166.  
  4167. gedge3Horzcz:
  4168.  
  4169.         jmp gzfillStart
  4170.  
  4171. gedge3Continuecz:
  4172.  
  4173.         mov ecx, yMid
  4174.         mov ebx, yTop
  4175.         sub ecx, ebx
  4176.  
  4177.         shl ebx, 2
  4178.         lea edi, rColor
  4179.         add edi, ebx
  4180.  
  4181.         xor ebx, ebx
  4182.         mov edx, cTop
  4183.         mov esi, yTop
  4184.  
  4185.         ror eax, 16
  4186.  
  4187.         align 4
  4188.  
  4189. gedge3Loopcz:
  4190.  
  4191.         cmp esi, 0
  4192.         jl gskipThisLine3cz
  4193.         cmp esi, 199
  4194.         jg gzfillStart
  4195.  
  4196.         mov bx, dx
  4197.         mov [edi], ebx
  4198.  
  4199. gskipThisLine3cz:
  4200.  
  4201.         add edx, eax
  4202.         adc edx, 0
  4203.         add edi, 4
  4204.         inc esi
  4205.         dec ecx
  4206.         jns gedge3Loopcz
  4207.  
  4208.         ; time to fill...
  4209.  
  4210. gzfillStart:
  4211.  
  4212.         mov eax, yTop
  4213.         mov ebx, yBot
  4214.  
  4215.         cmp eax, 0
  4216.         jge gzcheckBot
  4217.         xor eax, eax
  4218.         mov yTop, eax
  4219.  
  4220. gzcheckBot:
  4221.         cmp ebx, 199
  4222.         jle gzfillNOW
  4223.  
  4224.         mov ebx, 199
  4225.         mov yBot, ebx
  4226.  
  4227. gzfillNOW:
  4228.         lea esi, lEdge                  ; load edgelists
  4229.         lea edi, rEdge
  4230.  
  4231.         lea eax, lColor
  4232.         lea edx, rColor
  4233.  
  4234.         mov ecx, yMid                   ; midpoint
  4235.  
  4236.         mov esi, [esi + ecx*4]          ; find x values at midpoint
  4237.         mov edi, [edi + ecx*4]
  4238.  
  4239.         mov eax, [eax + ecx*4]          ; find color values at midpoint
  4240.         mov edx, [edx + ecx*4]
  4241.  
  4242.         sub eax, edx                    ; get dc
  4243.         sub esi, edi                    ; get dx
  4244.         test esi, 0FFFFFFFFh            ; make sure dx != 0
  4245.         jnz gzcrDiv
  4246.  
  4247.         mov eax, 0
  4248.         mov cRatio, eax
  4249.         jmp gzcrNodiv
  4250.  
  4251. gzcrDiv:
  4252.         shl eax, 8                      ; scale to 8.8 fixed point
  4253.         cdq                             ; get ready for div
  4254.         idiv esi                        ; calculate dc/dx used as the constant
  4255.         mov cRatio, eax                 ; color/x ratio for this plane
  4256.  
  4257. gzcrNodiv:
  4258.         lea esi, lEdge                  ; load edgelists again
  4259.         lea edi, rEdge
  4260.  
  4261.         lea eax, lColor
  4262.         lea edx, rColor
  4263.  
  4264.         lea ebx, lZ
  4265.         lea ebp, rZ
  4266.  
  4267.         mov ecx, yTop                   ; starting y value
  4268.         shl ecx, 2                      ; *4 to make an index into dword lists
  4269.  
  4270.         add esi, ecx                    ; add starting offset to edgelist
  4271.         add edi, ecx                    ; pointers
  4272.         add eax, ecx
  4273.         add edx, ecx
  4274.         add ebx, ecx
  4275.         add ebp, ecx
  4276.  
  4277.         shr ecx, 2                      ; /4 to get back to scanlines
  4278.  
  4279.         align 4
  4280.  
  4281. gzfillME: push ecx
  4282.  
  4283.  
  4284. gzx1OKToo:
  4285.         push esi                        ; save important registers
  4286.         push eax
  4287.         push edi
  4288.         push edx
  4289.         push ebx
  4290.         push ebp
  4291.  
  4292.         push [esi]                      ; push a LOT of arguments onto the
  4293.         push [ebx]                      ; stack for the procedure call
  4294.         push [eax]
  4295.         push [edi]
  4296.         push [ebp]
  4297.         push [edx]
  4298.         push ecx
  4299.  
  4300.         call gzHline                    ; draw a line
  4301.  
  4302.         pop ebp                         ; restore important registers
  4303.         pop ebx
  4304.         pop edx
  4305.         pop edi
  4306.         pop eax
  4307.         pop esi
  4308.  
  4309. gznextLine:
  4310.         pop ecx                         ; restore line counter
  4311.  
  4312.         add esi, 4                      ; next element in edgelists
  4313.         add edi, 4
  4314.         add eax, 4
  4315.         add edx, 4
  4316.         add ebx, 4
  4317.         add ebp, 4
  4318.  
  4319.         inc ecx                         ; next scanline
  4320.         cmp ecx, yBot                   ; are we done?
  4321.         jle gzfillME                    ; draw mo', foo'!
  4322.  
  4323. gzfillDone:
  4324.  
  4325.         pop esi
  4326.         pop edi
  4327.         pop ebp
  4328.  
  4329.         ret 48                          ; DONE!
  4330.  
  4331. gzpoly3 endp
  4332.  
  4333.         end             ; end of code (the ONLY) segment
  4334.  
  4335.